@jixo/cli 0.11.0 → 0.13.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.
Files changed (67) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +41 -67
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/daemon.d.ts +5 -0
  5. package/dist/commands/daemon.d.ts.map +1 -0
  6. package/dist/commands/daemon.js +20 -0
  7. package/dist/commands/daemon.js.map +1 -0
  8. package/dist/commands/doctor/config.d.ts.map +1 -1
  9. package/dist/commands/doctor/config.js +5 -18
  10. package/dist/commands/doctor/config.js.map +1 -1
  11. package/dist/commands/doctor/doctor.d.ts +1 -16
  12. package/dist/commands/doctor/doctor.d.ts.map +1 -1
  13. package/dist/commands/doctor/doctor.js +85 -52
  14. package/dist/commands/doctor/doctor.js.map +1 -1
  15. package/dist/commands/doctor/index.d.ts +1 -1
  16. package/dist/commands/doctor/index.d.ts.map +1 -1
  17. package/dist/commands/doctor/index.js +0 -11
  18. package/dist/commands/doctor/index.js.map +1 -1
  19. package/dist/commands/doctor/types.d.ts +17 -2
  20. package/dist/commands/doctor/types.d.ts.map +1 -1
  21. package/dist/commands/doctor/types.js.map +1 -1
  22. package/dist/commands/init.d.ts.map +1 -1
  23. package/dist/commands/init.js +32 -49
  24. package/dist/commands/init.js.map +1 -1
  25. package/dist/commands/tasks/AiTaskTui.d.ts +22 -0
  26. package/dist/commands/tasks/AiTaskTui.d.ts.map +1 -0
  27. package/dist/commands/tasks/AiTaskTui.js +52 -0
  28. package/dist/commands/tasks/AiTaskTui.js.map +1 -0
  29. package/dist/commands/tasks/ai-tasl-tui.d.ts +22 -0
  30. package/dist/commands/tasks/ai-tasl-tui.d.ts.map +1 -0
  31. package/dist/commands/tasks/ai-tasl-tui.js +53 -0
  32. package/dist/commands/tasks/ai-tasl-tui.js.map +1 -0
  33. package/dist/commands/tasks/ai-tools.d.ts +4 -10
  34. package/dist/commands/tasks/ai-tools.d.ts.map +1 -1
  35. package/dist/commands/tasks/ai-tools.js +15 -11
  36. package/dist/commands/tasks/ai-tools.js.map +1 -1
  37. package/dist/commands/tasks/model-providers.d.ts +5 -1
  38. package/dist/commands/tasks/model-providers.d.ts.map +1 -1
  39. package/dist/commands/tasks/model-providers.js +31 -0
  40. package/dist/commands/tasks/model-providers.js.map +1 -1
  41. package/dist/commands/tasks/run-ai-task.d.ts.map +1 -1
  42. package/dist/commands/tasks/run-ai-task.js +110 -126
  43. package/dist/commands/tasks/run-ai-task.js.map +1 -1
  44. package/dist/commands/tasks/run.d.ts +9 -6
  45. package/dist/commands/tasks/run.d.ts.map +1 -1
  46. package/dist/commands/tasks/run.js +38 -84
  47. package/dist/commands/tasks/run.js.map +1 -1
  48. package/dist/config.d.ts +5 -196
  49. package/dist/config.d.ts.map +1 -1
  50. package/dist/config.js +9 -21
  51. package/dist/config.js.map +1 -1
  52. package/dist/env.d.ts +2 -13
  53. package/dist/env.d.ts.map +1 -1
  54. package/dist/env.js +3 -13
  55. package/dist/env.js.map +1 -1
  56. package/dist/helper/handle-ai-error.js +1 -1
  57. package/dist/helper/handle-ai-error.js.map +1 -1
  58. package/dist/helper/logger.d.ts +3 -0
  59. package/dist/helper/logger.d.ts.map +1 -0
  60. package/dist/helper/logger.js +26 -0
  61. package/dist/helper/logger.js.map +1 -0
  62. package/dist/helper/resolve-ai-tasks.d.ts +7 -6
  63. package/dist/helper/resolve-ai-tasks.d.ts.map +1 -1
  64. package/dist/helper/resolve-ai-tasks.js +22 -19
  65. package/dist/helper/resolve-ai-tasks.js.map +1 -1
  66. package/dist/prompts.json +2 -14
  67. package/package.json +14 -10
@@ -1,90 +1,44 @@
1
- import { FileEntry, findChangedFilesSinceTime, Ignore, normalizeFilePath, walkFiles } from "@gaubee/nodekit";
2
- import { iter_map_not_null } from "@gaubee/util";
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import { loadConfig } from "../../config.js";
6
- import { loadJixoEnv } from "../../env.js";
7
- import { resolveAiTasks } from "../../helper/resolve-ai-tasks.js";
8
- import { runAiTask } from "./run-ai-task.js";
9
- export const run = async (_cwd, options) => {
10
- const cwd = normalizeFilePath(_cwd);
11
- const config = await loadConfig(cwd);
12
- const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : { isMatch: () => true };
13
- const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : { isMatch: () => true };
14
- const cwdIgnoreFilepath = path.join(cwd, ".gitignore");
15
- const ignore = [".git"];
16
- if (fs.existsSync(cwdIgnoreFilepath)) {
17
- ignore.push(...fs.readFileSync(cwdIgnoreFilepath, "utf-8").split("\n"));
18
- }
19
- const exitedTasks = new Set();
20
- let { force = false } = options;
21
- const { loopTimes: MAX_LOOP_TIMES = Infinity } = options;
22
- let currentTimes = 1;
23
- let retryTimes = 0;
24
- const MAX_RETRY_TIMES = 3;
25
- while (currentTimes <= MAX_LOOP_TIMES) {
26
- const ai_tasks = resolveAiTasks(cwd, config.tasks);
27
- const allFiles = [...walkFiles(cwd, { ignore })];
28
- let allDone = true;
29
- try {
30
- for (const ai_task of ai_tasks) {
31
- // 如果进度已经满了,并且没有任何依赖文件的变更,那么跳过这个任务
32
- if (!force) {
33
- if (ai_task.log.preProgress >= 1) {
34
- continue;
35
- }
36
- }
37
- if (exitedTasks.has(ai_task.name)) {
38
- continue;
39
- }
40
- const { dirs: task_dirs } = ai_task;
41
- if (!task_dirs.some((dir) => dirMatcher.isMatch(dir))) {
42
- continue;
43
- }
44
- if (!nameMatcher.isMatch(ai_task.name)) {
45
- continue;
46
- }
47
- const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;
48
- const changedFiles = (await findChangedFilesSinceTime(ai_task.log.preUpdateTime, cwd)) ?? allFiles;
49
- const task_changedFiles = isCwdTask
50
- ? { [cwd]: changedFiles }
51
- : task_dirs.reduce((tree, task_dir) => {
52
- tree[task_dir] = iter_map_not_null(changedFiles, (file) => {
53
- if (file.path.startsWith(task_dirs + "/")) {
54
- return new FileEntry(file.path, { cwd: task_dir, state: file.stats });
55
- }
56
- });
57
- return tree;
58
- }, {});
59
- const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, { ignore })]).flat();
60
- loadJixoEnv(cwd);
61
- /// 只要有一个任务执行了,那么allDone就要标记成false,进入下一次循环来判断
62
- allDone = false;
63
- await runAiTask(ai_task, currentTimes, task_allFiles, task_changedFiles);
64
- if (ai_task.exited) {
65
- exitedTasks.add(ai_task.name);
66
- }
67
- }
1
+ import { cyan, green, red, yellow } from "@gaubee/nodekit";
2
+ import { safeEnv } from "../../env.js";
3
+ export const run = async (options) => {
4
+ const { jobGoal, workDir, maxLoops, jobName, gitCommit } = options;
5
+ const coreUrl = safeEnv.JIXO_CORE_URL;
6
+ const apiKey = safeEnv.JIXO_API_KEY;
7
+ console.log(cyan(`🚀 Starting JIXO job...`));
8
+ console.log(` - Goal: ${jobGoal}`);
9
+ console.log(` - Target: ${coreUrl}`);
10
+ try {
11
+ const response = await fetch(`${coreUrl}/jixo/v1/jobs`, {
12
+ method: "POST",
13
+ headers: {
14
+ "Content-Type": "application/json",
15
+ Authorization: `Bearer ${apiKey}`,
16
+ },
17
+ body: JSON.stringify({
18
+ jobGoal,
19
+ workspaceDir: workDir, // Updated field name
20
+ maxLoops,
21
+ jobName,
22
+ gitCommit,
23
+ }),
24
+ });
25
+ if (!response.ok) {
26
+ const errorBody = await response.text();
27
+ throw new Error(`Failed to start job. Server responded with ${response.status}: ${errorBody}`);
68
28
  }
69
- catch {
70
- // 遇到异常,那么重试
71
- if (retryTimes < MAX_RETRY_TIMES) {
72
- retryTimes += 1;
73
- continue;
74
- }
75
- else {
76
- break;
77
- }
29
+ const result = await response.json();
30
+ console.log(green(`✅ Job successfully started with Run ID: ${result.runId}`));
31
+ }
32
+ catch (error) {
33
+ if (error instanceof TypeError && error.message.includes("fetch failed")) {
34
+ console.error(red("\n❌ Error: Could not connect to the JIXO Core service."));
35
+ console.error(yellow(` Please ensure the core service is running at ${coreUrl}.`));
36
+ console.error(yellow(` You can start it by running 'jixo daemon start' or running the core package directly.`));
78
37
  }
79
- // force 只能生效一次,避免无限循环
80
- force = false;
81
- currentTimes += 1;
82
- /// 成功一次后,retry计数就重制
83
- retryTimes = 0;
84
- /// 如果没有任务执行了,那么退出循环
85
- if (allDone) {
86
- break;
38
+ else {
39
+ console.error(red("\n❌ An unexpected error occurred:"), error);
87
40
  }
41
+ process.exit(1);
88
42
  }
89
43
  };
90
44
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"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","sourcesContent":["import {FileEntry, findChangedFilesSinceTime, Ignore, normalizeFilePath, walkFiles} from \"@gaubee/nodekit\";\nimport {iter_map_not_null} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {loadConfig} from \"../../config.js\";\nimport {loadJixoEnv} from \"../../env.js\";\nimport {resolveAiTasks} from \"../../helper/resolve-ai-tasks.js\";\nimport {runAiTask} from \"./run-ai-task.js\";\n\nexport const run = async (\n _cwd: string,\n options: {\n nameFilter: string[];\n dirFilter: string[];\n force?: boolean;\n loopTimes?: number;\n },\n) => {\n const cwd = normalizeFilePath(_cwd);\n const config = await loadConfig(cwd);\n\n const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : {isMatch: () => true};\n const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : {isMatch: () => true};\n const cwdIgnoreFilepath = path.join(cwd, \".gitignore\");\n const ignore = [\".git\"];\n if (fs.existsSync(cwdIgnoreFilepath)) {\n ignore.push(...fs.readFileSync(cwdIgnoreFilepath, \"utf-8\").split(\"\\n\"));\n }\n const exitedTasks = new Set<string>();\n\n let {force = false} = options;\n const {loopTimes: MAX_LOOP_TIMES = Infinity} = options;\n let currentTimes = 1;\n let retryTimes = 0;\n const MAX_RETRY_TIMES = 3;\n while (currentTimes <= MAX_LOOP_TIMES) {\n const ai_tasks = resolveAiTasks(cwd, config.tasks);\n\n const allFiles = [...walkFiles(cwd, {ignore})];\n let allDone = true;\n\n try {\n for (const ai_task of ai_tasks) {\n // 如果进度已经满了,并且没有任何依赖文件的变更,那么跳过这个任务\n if (!force) {\n if (ai_task.log.preProgress >= 1) {\n continue;\n }\n }\n if (exitedTasks.has(ai_task.name)) {\n continue;\n }\n\n const {dirs: task_dirs} = ai_task;\n if (!task_dirs.some((dir) => dirMatcher.isMatch(dir))) {\n continue;\n }\n if (!nameMatcher.isMatch(ai_task.name)) {\n continue;\n }\n const isCwdTask = cwd === task_dirs[0] && task_dirs.length === 1;\n\n const changedFiles = (await findChangedFilesSinceTime(ai_task.log.preUpdateTime, cwd)) ?? allFiles;\n\n const task_changedFiles = isCwdTask\n ? {[cwd]: changedFiles}\n : task_dirs.reduce(\n (tree, task_dir) => {\n tree[task_dir] = iter_map_not_null(changedFiles, (file) => {\n if (file.path.startsWith(task_dirs + \"/\")) {\n return new FileEntry(file.path, {cwd: task_dir, state: file.stats});\n }\n });\n return tree;\n },\n {} as Record<string, FileEntry[]>,\n );\n\n const task_allFiles = isCwdTask ? allFiles : task_dirs.map((task_dir) => [...walkFiles(task_dir, {ignore})]).flat();\n\n loadJixoEnv(cwd);\n\n /// 只要有一个任务执行了,那么allDone就要标记成false,进入下一次循环来判断\n allDone = false;\n await runAiTask(ai_task, currentTimes, task_allFiles, task_changedFiles);\n\n if (ai_task.exited) {\n exitedTasks.add(ai_task.name);\n }\n }\n } catch {\n // 遇到异常,那么重试\n if (retryTimes < MAX_RETRY_TIMES) {\n retryTimes += 1;\n continue;\n } else {\n break;\n }\n }\n // force 只能生效一次,避免无限循环\n force = false;\n currentTimes += 1;\n /// 成功一次后,retry计数就重制\n retryTimes = 0;\n\n /// 如果没有任务执行了,那么退出循环\n if (allDone) {\n break;\n }\n }\n};\n"]}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAC,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAUrC,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,OAAmB,EAAE,EAAE;IAC/C,MAAM,EAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAC,GAAG,OAAO,CAAC;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAEpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,eAAe,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,MAAM,EAAE;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,OAAO;gBACP,YAAY,EAAE,OAAO,EAAE,qBAAqB;gBAC5C,QAAQ;gBACR,OAAO;gBACP,SAAS;aACV,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,8CAA8C,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC,CAAC;QACjG,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,2CAA2C,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC,CAAC;YAC7E,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,mDAAmD,OAAO,GAAG,CAAC,CAAC,CAAC;YACrF,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,0FAA0F,CAAC,CAAC,CAAC;QACpH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,mCAAmC,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC","sourcesContent":["import {cyan, green, red, yellow} from \"@gaubee/nodekit\";\nimport {safeEnv} from \"../../env.js\";\n\ninterface RunOptions {\n jobGoal: string;\n workDir: string;\n maxLoops: number;\n jobName?: string;\n gitCommit?: boolean;\n}\n\nexport const run = async (options: RunOptions) => {\n const {jobGoal, workDir, maxLoops, jobName, gitCommit} = options;\n const coreUrl = safeEnv.JIXO_CORE_URL;\n const apiKey = safeEnv.JIXO_API_KEY;\n\n console.log(cyan(`🚀 Starting JIXO job...`));\n console.log(` - Goal: ${jobGoal}`);\n console.log(` - Target: ${coreUrl}`);\n\n try {\n const response = await fetch(`${coreUrl}/jixo/v1/jobs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n jobGoal,\n workspaceDir: workDir, // Updated field name\n maxLoops,\n jobName,\n gitCommit,\n }),\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new Error(`Failed to start job. Server responded with ${response.status}: ${errorBody}`);\n }\n\n const result = await response.json();\n console.log(green(`✅ Job successfully started with Run ID: ${result.runId}`));\n } catch (error) {\n if (error instanceof TypeError && error.message.includes(\"fetch failed\")) {\n console.error(red(\"\\n❌ Error: Could not connect to the JIXO Core service.\"));\n console.error(yellow(` Please ensure the core service is running at ${coreUrl}.`));\n console.error(yellow(` You can start it by running 'jixo daemon start' or running the core package directly.`));\n } else {\n console.error(red(\"\\n An unexpected error occurred:\"), error);\n }\n process.exit(1);\n }\n};\n"]}
package/dist/config.d.ts CHANGED
@@ -1,206 +1,15 @@
1
1
  import z from "zod";
2
- declare const zJixoTask: z.ZodUnion<[z.ZodString, z.ZodObject<{
3
- type: z.ZodLiteral<"file">;
4
- name: z.ZodOptional<z.ZodString>;
5
- filename: z.ZodString;
6
- }, "strip", z.ZodTypeAny, {
7
- filename: string;
8
- type: "file";
9
- name?: string | undefined;
10
- }, {
11
- filename: string;
12
- type: "file";
13
- name?: string | undefined;
14
- }>, z.ZodObject<{
15
- type: z.ZodLiteral<"dir">;
16
- dirname: z.ZodString;
17
- }, "strip", z.ZodTypeAny, {
18
- type: "dir";
19
- dirname: string;
20
- }, {
21
- type: "dir";
22
- dirname: string;
23
- }>, z.ZodObject<{
24
- type: z.ZodLiteral<"prompt">;
25
- name: z.ZodOptional<z.ZodString>;
26
- content: z.ZodString;
27
- }, "strip", z.ZodTypeAny, {
28
- type: "prompt";
29
- content: string;
30
- name?: string | undefined;
31
- }, {
32
- type: "prompt";
33
- content: string;
34
- name?: string | undefined;
35
- }>]>;
36
2
  declare const zJixoConfig: z.ZodObject<{
37
- tasks: z.ZodUnion<[z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
38
- type: z.ZodLiteral<"file">;
39
- name: z.ZodOptional<z.ZodString>;
40
- filename: z.ZodString;
41
- }, "strip", z.ZodTypeAny, {
42
- filename: string;
43
- type: "file";
44
- name?: string | undefined;
45
- }, {
46
- filename: string;
47
- type: "file";
48
- name?: string | undefined;
49
- }>, z.ZodObject<{
50
- type: z.ZodLiteral<"dir">;
51
- dirname: z.ZodString;
52
- }, "strip", z.ZodTypeAny, {
53
- type: "dir";
54
- dirname: string;
55
- }, {
56
- type: "dir";
57
- dirname: string;
58
- }>, z.ZodObject<{
59
- type: z.ZodLiteral<"prompt">;
60
- name: z.ZodOptional<z.ZodString>;
61
- content: z.ZodString;
62
- }, "strip", z.ZodTypeAny, {
63
- type: "prompt";
64
- content: string;
65
- name?: string | undefined;
66
- }, {
67
- type: "prompt";
68
- content: string;
69
- name?: string | undefined;
70
- }>]>, "many">, z.ZodUnion<[z.ZodString, z.ZodObject<{
71
- type: z.ZodLiteral<"file">;
72
- name: z.ZodOptional<z.ZodString>;
73
- filename: z.ZodString;
74
- }, "strip", z.ZodTypeAny, {
75
- filename: string;
76
- type: "file";
77
- name?: string | undefined;
78
- }, {
79
- filename: string;
80
- type: "file";
81
- name?: string | undefined;
82
- }>, z.ZodObject<{
83
- type: z.ZodLiteral<"dir">;
84
- dirname: z.ZodString;
85
- }, "strip", z.ZodTypeAny, {
86
- type: "dir";
87
- dirname: string;
88
- }, {
89
- type: "dir";
90
- dirname: string;
91
- }>, z.ZodObject<{
92
- type: z.ZodLiteral<"prompt">;
93
- name: z.ZodOptional<z.ZodString>;
94
- content: z.ZodString;
95
- }, "strip", z.ZodTypeAny, {
96
- type: "prompt";
97
- content: string;
98
- name?: string | undefined;
99
- }, {
100
- type: "prompt";
101
- content: string;
102
- name?: string | undefined;
103
- }>]>]>;
3
+ coreUrl: z.ZodDefault<z.ZodOptional<z.ZodString>>;
104
4
  }, "strip", z.ZodTypeAny, {
105
- tasks: string | {
106
- filename: string;
107
- type: "file";
108
- name?: string | undefined;
109
- } | {
110
- type: "dir";
111
- dirname: string;
112
- } | {
113
- type: "prompt";
114
- content: string;
115
- name?: string | undefined;
116
- } | (string | {
117
- filename: string;
118
- type: "file";
119
- name?: string | undefined;
120
- } | {
121
- type: "dir";
122
- dirname: string;
123
- } | {
124
- type: "prompt";
125
- content: string;
126
- name?: string | undefined;
127
- })[];
5
+ coreUrl: string;
128
6
  }, {
129
- tasks: string | {
130
- filename: string;
131
- type: "file";
132
- name?: string | undefined;
133
- } | {
134
- type: "dir";
135
- dirname: string;
136
- } | {
137
- type: "prompt";
138
- content: string;
139
- name?: string | undefined;
140
- } | (string | {
141
- filename: string;
142
- type: "file";
143
- name?: string | undefined;
144
- } | {
145
- type: "dir";
146
- dirname: string;
147
- } | {
148
- type: "prompt";
149
- content: string;
150
- name?: string | undefined;
151
- })[];
7
+ coreUrl?: string | undefined;
152
8
  }>;
153
- export type JixoTask = z.output<typeof zJixoTask>;
154
9
  export type JixoConfig = z.output<typeof zJixoConfig>;
155
10
  export declare const defineConfig: (config: Partial<JixoConfig>) => {
156
- tasks: string | {
157
- filename: string;
158
- type: "file";
159
- name?: string | undefined;
160
- } | {
161
- type: "dir";
162
- dirname: string;
163
- } | {
164
- type: "prompt";
165
- content: string;
166
- name?: string | undefined;
167
- } | (string | {
168
- filename: string;
169
- type: "file";
170
- name?: string | undefined;
171
- } | {
172
- type: "dir";
173
- dirname: string;
174
- } | {
175
- type: "prompt";
176
- content: string;
177
- name?: string | undefined;
178
- })[];
11
+ coreUrl: string;
179
12
  };
180
- export declare const loadConfig: (dir: string) => Promise<{
181
- tasks: string | {
182
- filename: string;
183
- type: "file";
184
- name?: string | undefined;
185
- } | {
186
- type: "dir";
187
- dirname: string;
188
- } | {
189
- type: "prompt";
190
- content: string;
191
- name?: string | undefined;
192
- } | (string | {
193
- filename: string;
194
- type: "file";
195
- name?: string | undefined;
196
- } | {
197
- type: "dir";
198
- dirname: string;
199
- } | {
200
- type: "prompt";
201
- content: string;
202
- name?: string | undefined;
203
- })[];
204
- }>;
13
+ export declare const loadConfig: (dir: string) => Promise<JixoConfig>;
205
14
  export {};
206
15
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgBb,CAAC;AACH,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEf,CAAC;AAKH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,eAAO,MAAM,YAAY,GAAI,QAAQ,OAAO,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAEvD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,KAAK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;EAI3C,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,QAAA,MAAM,WAAW;;;;;;EAEf,CAAC;AAMH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,YAAY,GAAI,QAAQ,OAAO,CAAC,UAAU,CAAC;;CAEvD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,UAAU,CAOhE,CAAC"}
package/dist/config.js CHANGED
@@ -1,35 +1,23 @@
1
1
  import { cosmiconfig } from "cosmiconfig";
2
2
  import { defu } from "defu";
3
3
  import z from "zod";
4
- const zJixoTask = z.union([
5
- z.string(),
6
- z.object({
7
- type: z.literal("file"),
8
- name: z.string().optional(),
9
- filename: z.string(),
10
- }),
11
- z.object({
12
- type: z.literal("dir"),
13
- dirname: z.string(),
14
- }),
15
- z.object({
16
- type: z.literal("prompt"),
17
- name: z.string().optional(),
18
- content: z.string(),
19
- }),
20
- ]);
4
+ const DEFAULT_CORE_URL = "http://localhost:4111";
21
5
  const zJixoConfig = z.object({
22
- tasks: z.union([z.array(zJixoTask), zJixoTask]),
6
+ coreUrl: z.string().url().optional().default(DEFAULT_CORE_URL),
23
7
  });
24
8
  const defaultConfig = {
25
- tasks: { type: "dir", dirname: ".jixo" },
9
+ coreUrl: DEFAULT_CORE_URL,
26
10
  };
27
11
  export const defineConfig = (config) => {
28
12
  return zJixoConfig.parse(config);
29
13
  };
30
14
  export const loadConfig = async (dir) => {
31
- const explorer = cosmiconfig("jixo");
15
+ const explorer = cosmiconfig("jixo", {
16
+ searchStrategy: "global",
17
+ });
32
18
  const loaded = await explorer.search(dir);
33
- return defu(loaded?.config, defaultConfig);
19
+ // Use Zod to parse the loaded config, which applies defaults if properties are missing.
20
+ return defu(zJixoConfig.parse(loaded?.config || {}), defaultConfig);
34
21
  };
22
+ console.log(defineConfig({}));
35
23
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAC1B,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;IACxB,CAAC,CAAC,MAAM,EAAE;IACV,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;KACrB,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC;CACH,CAAC,CAAC;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;CAChD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAe;IAChC,KAAK,EAAE,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAC;CACvC,CAAC;AAGF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAA2B,EAAE,EAAE;IAC1D,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,MAAM,EAAE,MAAoB,EAAE,aAAa,CAAC,CAAC;AAC3D,CAAC,CAAC","sourcesContent":["import {cosmiconfig} from \"cosmiconfig\";\nimport {defu} from \"defu\";\nimport z from \"zod\";\n\nconst zJixoTask = z.union([\n z.string(),\n z.object({\n type: z.literal(\"file\"),\n name: z.string().optional(),\n filename: z.string(),\n }),\n z.object({\n type: z.literal(\"dir\"),\n dirname: z.string(),\n }),\n z.object({\n type: z.literal(\"prompt\"),\n name: z.string().optional(),\n content: z.string(),\n }),\n]);\nconst zJixoConfig = z.object({\n tasks: z.union([z.array(zJixoTask), zJixoTask]),\n});\n\nconst defaultConfig: JixoConfig = {\n tasks: {type: \"dir\", dirname: \".jixo\"},\n};\nexport type JixoTask = z.output<typeof zJixoTask>;\nexport type JixoConfig = z.output<typeof zJixoConfig>;\nexport const defineConfig = (config: Partial<JixoConfig>) => {\n return zJixoConfig.parse(config);\n};\n\nexport const loadConfig = async (dir: string) => {\n const explorer = cosmiconfig(\"jixo\");\n const loaded = await explorer.search(dir);\n return defu(loaded?.config as JixoConfig, defaultConfig);\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAC1B,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC;CAC/D,CAAC,CAAC;AAEH,MAAM,aAAa,GAAe;IAChC,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAIF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAA2B,EAAE,EAAE;IAC1D,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAuB,EAAE;IACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE;QACnC,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1C,wFAAwF;IACxF,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;AACtE,CAAC,CAAC;AACF,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC","sourcesContent":["import {cosmiconfig} from \"cosmiconfig\";\nimport {defu} from \"defu\";\nimport z from \"zod\";\nconst DEFAULT_CORE_URL = \"http://localhost:4111\";\nconst zJixoConfig = z.object({\n coreUrl: z.string().url().optional().default(DEFAULT_CORE_URL),\n});\n\nconst defaultConfig: JixoConfig = {\n coreUrl: DEFAULT_CORE_URL,\n};\n\nexport type JixoConfig = z.output<typeof zJixoConfig>;\n\nexport const defineConfig = (config: Partial<JixoConfig>) => {\n return zJixoConfig.parse(config);\n};\n\nexport const loadConfig = async (dir: string): Promise<JixoConfig> => {\n const explorer = cosmiconfig(\"jixo\", {\n searchStrategy: \"global\",\n });\n const loaded = await explorer.search(dir);\n // Use Zod to parse the loaded config, which applies defaults if properties are missing.\n return defu(zJixoConfig.parse(loaded?.config || {}), defaultConfig);\n};\nconsole.log(defineConfig({}));\n"]}
package/dist/env.d.ts CHANGED
@@ -1,17 +1,6 @@
1
1
  export declare const loadJixoEnv: (dir: string) => void;
2
2
  export declare const safeEnv: import("@gaubee/node").DefineEnvChain<"JIXO", import("@gaubee/node").DefineEnv<"JIXO", {
3
- DEEPSEEK_API_KEY: string;
4
- DEEPSEEK_BASE_URL: string;
5
- ANTHROPIC_API_KEY: string;
6
- ANTHROPIC_BASE_URL: string;
7
- OPENAI_API_KEY: string;
8
- OPENAI_BASE_URL: string;
9
- OPENAI_ORGANIZATION: string;
10
- GOOGLE_API_KEY: string;
11
- GOOGLE_BASE_URL: string;
12
- XAI_BASE_URL: string;
13
- XAI_API_KEY: string;
14
- DEEPINFRA_BASE_URL: string;
15
- DEEPINFRA_API_KEY: string;
3
+ CORE_URL: string;
4
+ API_KEY: string;
16
5
  }>>;
17
6
  //# sourceMappingURL=env.d.ts.map
package/dist/env.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,SAKtC,CAAC;AAGF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;GAmBlB,CAAC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,SAKtC,CAAC;AAKF,eAAO,MAAM,OAAO;;;GAGlB,CAAC"}
package/dist/env.js CHANGED
@@ -7,20 +7,10 @@ export const loadJixoEnv = (dir) => {
7
7
  process.loadEnvFile(cwdJixoEnvFilepath);
8
8
  }
9
9
  };
10
+ // Load environment from the current working directory when the module is imported.
10
11
  loadJixoEnv(process.cwd());
11
12
  export const safeEnv = defineEnv("JIXO", {
12
- DEEPSEEK_API_KEY: "",
13
- DEEPSEEK_BASE_URL: "",
14
- ANTHROPIC_API_KEY: "",
15
- ANTHROPIC_BASE_URL: "",
16
- OPENAI_API_KEY: "",
17
- OPENAI_BASE_URL: "",
18
- OPENAI_ORGANIZATION: "",
19
- GOOGLE_API_KEY: "",
20
- GOOGLE_BASE_URL: "",
21
- XAI_BASE_URL: "",
22
- XAI_API_KEY: "",
23
- DEEPINFRA_BASE_URL: "",
24
- DEEPINFRA_API_KEY: "",
13
+ CORE_URL: "http://localhost:4111",
14
+ API_KEY: "",
25
15
  });
26
16
  //# sourceMappingURL=env.js.map
package/dist/env.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE;IACzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvD,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC,CAAC;AACF,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE;IACvC,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IAErB,iBAAiB,EAAE,EAAE;IACrB,kBAAkB,EAAE,EAAE;IAEtB,cAAc,EAAE,EAAE;IAClB,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;IAEvB,cAAc,EAAE,EAAE;IAClB,eAAe,EAAE,EAAE;IAEnB,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,EAAE;IAEf,kBAAkB,EAAE,EAAE;IACtB,iBAAiB,EAAE,EAAE;CACtB,CAAC,CAAC","sourcesContent":["import {defineEnv} from \"@gaubee/node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport const loadJixoEnv = (dir: string) => {\n const cwdJixoEnvFilepath = path.join(dir, \".jixo.env\");\n if (fs.existsSync(cwdJixoEnvFilepath)) {\n process.loadEnvFile(cwdJixoEnvFilepath);\n }\n};\nloadJixoEnv(process.cwd());\n\nexport const safeEnv = defineEnv(\"JIXO\", {\n DEEPSEEK_API_KEY: \"\",\n DEEPSEEK_BASE_URL: \"\",\n\n ANTHROPIC_API_KEY: \"\",\n ANTHROPIC_BASE_URL: \"\",\n\n OPENAI_API_KEY: \"\",\n OPENAI_BASE_URL: \"\",\n OPENAI_ORGANIZATION: \"\",\n\n GOOGLE_API_KEY: \"\",\n GOOGLE_BASE_URL: \"\",\n\n XAI_BASE_URL: \"\",\n XAI_API_KEY: \"\",\n\n DEEPINFRA_BASE_URL: \"\",\n DEEPINFRA_API_KEY: \"\",\n});\n"]}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,EAAE;IACzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvD,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC,CAAC;AAEF,mFAAmF;AACnF,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE;IACvC,QAAQ,EAAE,uBAAuB;IACjC,OAAO,EAAE,EAAE;CACZ,CAAC,CAAC","sourcesContent":["import {defineEnv} from \"@gaubee/node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport const loadJixoEnv = (dir: string) => {\n const cwdJixoEnvFilepath = path.join(dir, \".jixo.env\");\n if (fs.existsSync(cwdJixoEnvFilepath)) {\n process.loadEnvFile(cwdJixoEnvFilepath);\n }\n};\n\n// Load environment from the current working directory when the module is imported.\nloadJixoEnv(process.cwd());\n\nexport const safeEnv = defineEnv(\"JIXO\", {\n CORE_URL: \"http://localhost:4111\",\n API_KEY: \"\",\n});\n"]}
@@ -29,7 +29,7 @@ const handleAPICallError = async (error, loading) => {
29
29
  }
30
30
  try {
31
31
  if (error.isRetryable) {
32
- const safeData = geminiErrorSchema.safeParse(error.data);
32
+ const safeData = geminiErrorSchema.safeParse(JSON.parse(error.responseBody));
33
33
  if (!safeData.success) {
34
34
  throw safeData.error;
35
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handle-ai-error.js","sourceRoot":"","sources":["../../src/helper/handle-ai-error.ts"],"names":[],"mappings":"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","sourcesContent":["import {gray, red, yellow, type Spinner} from \"@gaubee/nodekit\";\r\nimport {delay} from \"@gaubee/util\";\r\nimport {APICallError, RetryError} from \"ai\";\r\nimport ms from \"ms\";\r\nimport {match} from \"ts-pattern\";\r\nimport z from \"zod\";\r\ntype Loading = Pick<Spinner, \"prefixText\" | \"text\">;\r\n\r\nexport const handleError = async (error: unknown, loading: Loading) => {\r\n for (const handle of [handleAPICallError, handleRetryError]) {\r\n const matched = await handle(error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleRetryError = async (error: unknown, loading: Loading) => {\r\n if (!RetryError.isInstance(error)) {\r\n return;\r\n }\r\n for (const inner_error of error.errors) {\r\n const matched = await handleAPICallError(inner_error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleAPICallError = async (error: unknown, loading: Loading) => {\r\n if (!APICallError.isInstance(error)) {\r\n return;\r\n }\r\n try {\r\n if (error.isRetryable) {\r\n const safeData = geminiErrorSchema.safeParse(error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n const retryDetail = safeData.data.error.details.find((d) => \"retryDelay\" in d);\r\n if (retryDetail) {\r\n const retryDelay = ms(retryDetail.retryDelay as ms.StringValue);\r\n\r\n if (typeof retryDelay === \"number\") {\r\n await waitRetryDelay(loading, retryDelay, (loading.text = yellow(error.message)));\r\n return true;\r\n }\r\n }\r\n } else {\r\n const safeData = commonErrorSchema.safeParse(error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n await match(safeData.data.error)\r\n /// 余额不足\r\n .with({message: \"Insufficient Balance\"}, async () => {\r\n /// 30s重试\r\n await waitRetryDelay(loading, 1000 * 30, (loading.text = red(\"Insufficient Balance\") + \"\\n\" + red(error.url)));\r\n })\r\n .otherwise(() => {\r\n throw error;\r\n });\r\n return true;\r\n }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", error);\r\n }\r\n};\r\n\r\nconst commonErrorSchema = z.object({\r\n error: z.object({\r\n message: z.string(),\r\n type: z.string(),\r\n param: z.any(),\r\n code: z.string(),\r\n }),\r\n});\r\n\r\nconst geminiErrorSchema = z.object({\r\n error: z.object({\r\n code: z.number(),\r\n message: z.string(),\r\n status: z.string(),\r\n details: z.array(\r\n z.union([\r\n z.object({\r\n \"@type\": z.string(),\r\n violations: z.array(\r\n z.object({\r\n quotaMetric: z.string(),\r\n quotaId: z.string(),\r\n quotaDimensions: z.object({\r\n location: z.string(),\r\n model: z.string(),\r\n }),\r\n quotaValue: z.string(),\r\n }),\r\n ),\r\n }),\r\n z.object({\r\n \"@type\": z.string(),\r\n links: z.array(z.object({description: z.string(), url: z.string()})),\r\n }),\r\n z.object({\"@type\": z.string(), retryDelay: z.string()}),\r\n ]),\r\n ),\r\n }),\r\n});\r\n\r\nconst waitRetryDelay = async (loading: Loading, retryDelay: number, message: string) => {\r\n const {prefixText, text} = loading;\r\n let remainingDelay = retryDelay;\r\n const tickInterval = 1000;\r\n const tick = () => {\r\n loading.prefixText = \"⏲️ \";\r\n loading.text = [\r\n //\r\n message,\r\n \" \" + gray(\"─\".repeat(Math.max(4, process.stdout.columns - 2))),\r\n `Retrying in ${ms(remainingDelay)}...`,\r\n ].join(\"\\n\");\r\n remainingDelay -= tickInterval;\r\n };\r\n tick();\r\n\r\n const ti = setInterval(tick, tickInterval);\r\n await delay(retryDelay);\r\n clearInterval(ti);\r\n\r\n // 回滚\r\n loading.prefixText = prefixText;\r\n loading.text = text;\r\n};\r\n"]}
1
+ {"version":3,"file":"handle-ai-error.js","sourceRoot":"","sources":["../../src/helper/handle-ai-error.ts"],"names":[],"mappings":"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","sourcesContent":["import {gray, red, yellow, type Spinner} from \"@gaubee/nodekit\";\r\nimport {delay} from \"@gaubee/util\";\r\nimport {APICallError, RetryError} from \"ai\";\r\nimport ms from \"ms\";\r\nimport {match} from \"ts-pattern\";\r\nimport z from \"zod\";\r\ntype Loading = Pick<Spinner, \"prefixText\" | \"text\">;\r\n\r\nexport const handleError = async (error: unknown, loading: Loading) => {\r\n for (const handle of [handleAPICallError, handleRetryError]) {\r\n const matched = await handle(error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleRetryError = async (error: unknown, loading: Loading) => {\r\n if (!RetryError.isInstance(error)) {\r\n return;\r\n }\r\n for (const inner_error of error.errors) {\r\n const matched = await handleAPICallError(inner_error, loading);\r\n if (matched) {\r\n return true;\r\n }\r\n }\r\n};\r\n\r\nconst handleAPICallError = async (error: unknown, loading: Loading) => {\r\n if (!APICallError.isInstance(error)) {\r\n return;\r\n }\r\n try {\r\n if (error.isRetryable) {\r\n const safeData = geminiErrorSchema.safeParse(JSON.parse(error.responseBody!));\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n const retryDetail = safeData.data.error.details.find((d) => \"retryDelay\" in d);\r\n if (retryDetail) {\r\n const retryDelay = ms(retryDetail.retryDelay as ms.StringValue);\r\n\r\n if (typeof retryDelay === \"number\") {\r\n await waitRetryDelay(loading, retryDelay, (loading.text = yellow(error.message)));\r\n return true;\r\n }\r\n }\r\n } else {\r\n const safeData = commonErrorSchema.safeParse(error.data);\r\n if (!safeData.success) {\r\n throw safeData.error;\r\n }\r\n await match(safeData.data.error)\r\n /// 余额不足\r\n .with({message: \"Insufficient Balance\"}, async () => {\r\n /// 30s重试\r\n await waitRetryDelay(loading, 1000 * 30, (loading.text = red(\"Insufficient Balance\") + \"\\n\" + red(error.url)));\r\n })\r\n .otherwise(() => {\r\n throw error;\r\n });\r\n return true;\r\n }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", error);\r\n }\r\n};\r\n\r\nconst commonErrorSchema = z.object({\r\n error: z.object({\r\n message: z.string(),\r\n type: z.string(),\r\n param: z.any(),\r\n code: z.string(),\r\n }),\r\n});\r\n\r\nconst geminiErrorSchema = z.object({\r\n error: z.object({\r\n code: z.number(),\r\n message: z.string(),\r\n status: z.string(),\r\n details: z.array(\r\n z.union([\r\n z.object({\r\n \"@type\": z.string(),\r\n violations: z.array(\r\n z.object({\r\n quotaMetric: z.string(),\r\n quotaId: z.string(),\r\n quotaDimensions: z.object({\r\n location: z.string(),\r\n model: z.string(),\r\n }),\r\n quotaValue: z.string(),\r\n }),\r\n ),\r\n }),\r\n z.object({\r\n \"@type\": z.string(),\r\n links: z.array(z.object({description: z.string(), url: z.string()})),\r\n }),\r\n z.object({\"@type\": z.string(), retryDelay: z.string()}),\r\n ]),\r\n ),\r\n }),\r\n});\r\n\r\nconst waitRetryDelay = async (loading: Loading, retryDelay: number, message: string) => {\r\n const {prefixText, text} = loading;\r\n let remainingDelay = retryDelay;\r\n const tickInterval = 1000;\r\n const tick = () => {\r\n loading.prefixText = \"⏲️ \";\r\n loading.text = [\r\n //\r\n message,\r\n \" \" + gray(\"─\".repeat(Math.max(4, process.stdout.columns - 2))),\r\n `Retrying in ${ms(remainingDelay)}...`,\r\n ].join(\"\\n\");\r\n remainingDelay -= tickInterval;\r\n };\r\n tick();\r\n\r\n const ti = setInterval(tick, tickInterval);\r\n await delay(retryDelay);\r\n clearInterval(ti);\r\n\r\n // 回滚\r\n loading.prefixText = prefixText;\r\n loading.text = text;\r\n};\r\n"]}
@@ -0,0 +1,3 @@
1
+ import createDebug from "debug";
2
+ export { createDebug };
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/helper/logger.ts"],"names":[],"mappings":"AAEA,OAAO,WAAW,MAAM,OAAO,CAAC;AAuBhC,OAAO,EAAC,WAAW,EAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { gray, red } from "@gaubee/nodekit";
2
+ import { AISDKError } from "ai";
3
+ import createDebug from "debug";
4
+ createDebug.formatters.y = (v) => {
5
+ return JSON.stringify(v, (_k, v) => {
6
+ if (typeof v === "string") {
7
+ let slice_len = 0;
8
+ if (v.length > 200) {
9
+ slice_len = 50;
10
+ }
11
+ if (v.length > 100) {
12
+ slice_len = 30;
13
+ }
14
+ if (slice_len > 0) {
15
+ return `<string:${v.length}>${v.slice(0, slice_len)}${gray("...")}${v.slice(-slice_len)}`;
16
+ }
17
+ return v;
18
+ }
19
+ if (AISDKError.isInstance(v)) {
20
+ return red(v.message);
21
+ }
22
+ return v;
23
+ });
24
+ };
25
+ export { createDebug };
26
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/helper/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,GAAG,EAAC,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAC9B,OAAO,WAAW,MAAM,OAAO,CAAC;AAEhC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE;IAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACnB,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;gBACnB,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,OAAO,WAAW,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5F,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,OAAO,EAAC,WAAW,EAAC,CAAC","sourcesContent":["import {gray, red} from \"@gaubee/nodekit\";\nimport {AISDKError} from \"ai\";\nimport createDebug from \"debug\";\n\ncreateDebug.formatters.y = (v) => {\n return JSON.stringify(v, (_k, v) => {\n if (typeof v === \"string\") {\n let slice_len = 0;\n if (v.length > 200) {\n slice_len = 50;\n }\n if (v.length > 100) {\n slice_len = 30;\n }\n if (slice_len > 0) {\n return `<string:${v.length}>${v.slice(0, slice_len)}${gray(\"...\")}${v.slice(-slice_len)}`;\n }\n return v;\n }\n if (AISDKError.isInstance(v)) {\n return red(v.message);\n }\n return v;\n });\n};\nexport {createDebug};\n"]}
@@ -5,25 +5,26 @@ import { type JixoConfig } from "../config.js";
5
5
  * @param config_tasks
6
6
  * @returns
7
7
  */
8
- export declare const resolveAiTasks: (cwd: string, config_tasks: JixoConfig["tasks"]) => ({
8
+ export declare const resolveAiTasks: (cwd: string, config_tasks: JixoConfig["tasks"], current_job_loop_count: number) => ({
9
9
  data: {
10
10
  [key: string]: any;
11
11
  };
12
12
  content: string;
13
13
  } & Readonly<{
14
- name: string;
14
+ runner: string;
15
+ jobName: string;
16
+ loopCount: number;
15
17
  filepath: string;
16
- exited: boolean;
18
+ exitCode: number | null;
17
19
  exitReason: string;
18
- exit: (reason: string) => void;
20
+ exit: (code: number, reason: string) => void;
19
21
  cwd: string;
20
22
  dirs: string[];
21
23
  agents: string[];
22
24
  model: string;
23
25
  startTime: string;
24
26
  maxTurns: number;
25
- executor: string;
26
- allExecutors: string[];
27
+ otherRunners: string[];
27
28
  log: Readonly<{
28
29
  name: string;
29
30
  filepath: string;