@jixo/cli 0.8.0 → 0.10.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.
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/tasks/run.ts"],"names":[],"mappings":"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","sourcesContent":["import {FileEntry, 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 {findChangedFilesSinceCommit} from \"../../helper/find-changes.js\";\nimport {resolveAiTasks} from \"../../helper/resolve-ai-tasks.js\";\nimport {runAiTask} from \"./run-ai-task.js\";\n\nexport const run = async (_cwd: string, options: {nameFilter: string[]; dirFilter: string[]}) => {\n const cwd = normalizeFilePath(_cwd);\n const config = await loadConfig(cwd);\n const ai_tasks = resolveAiTasks(cwd, config.tasks);\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\n const allFiles = [...walkFiles(cwd, {ignore})];\n const changedFiles = (await findChangedFilesSinceCommit(\"@jixo\", cwd)).filter((file) => {\n return file.path.startsWith(cwd + \"/\");\n });\n\n // const run_tasks: Array<Func> = [];\n for (const ai_task of ai_tasks) {\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 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 await runAiTask(ai_task, task_allFiles, task_changedFiles);\n }\n};\n"]}
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 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\n while (currentTimes <= MAX_LOOP_TIMES) {\n const ai_tasks = resolveAiTasks(cwd, config.tasks);\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\n const allFiles = [...walkFiles(cwd, {ignore})];\n let allDone = true;\n\n try {\n for (const ai_task of ai_tasks) {\n // 如果进度已经满了,那么跳过\n if (ai_task.preProgress >= 1 && !force) {\n continue;\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.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, task_allFiles, task_changedFiles);\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"]}
package/dist/config.d.ts CHANGED
@@ -4,12 +4,12 @@ declare const zJixoTask: z.ZodUnion<[z.ZodString, z.ZodObject<{
4
4
  name: z.ZodOptional<z.ZodString>;
5
5
  filename: z.ZodString;
6
6
  }, "strip", z.ZodTypeAny, {
7
- type: "file";
8
7
  filename: string;
8
+ type: "file";
9
9
  name?: string | undefined;
10
10
  }, {
11
- type: "file";
12
11
  filename: string;
12
+ type: "file";
13
13
  name?: string | undefined;
14
14
  }>, z.ZodObject<{
15
15
  type: z.ZodLiteral<"dir">;
@@ -39,12 +39,12 @@ declare const zJixoConfig: z.ZodObject<{
39
39
  name: z.ZodOptional<z.ZodString>;
40
40
  filename: z.ZodString;
41
41
  }, "strip", z.ZodTypeAny, {
42
- type: "file";
43
42
  filename: string;
43
+ type: "file";
44
44
  name?: string | undefined;
45
45
  }, {
46
- type: "file";
47
46
  filename: string;
47
+ type: "file";
48
48
  name?: string | undefined;
49
49
  }>, z.ZodObject<{
50
50
  type: z.ZodLiteral<"dir">;
@@ -72,12 +72,12 @@ declare const zJixoConfig: z.ZodObject<{
72
72
  name: z.ZodOptional<z.ZodString>;
73
73
  filename: z.ZodString;
74
74
  }, "strip", z.ZodTypeAny, {
75
- type: "file";
76
75
  filename: string;
76
+ type: "file";
77
77
  name?: string | undefined;
78
78
  }, {
79
- type: "file";
80
79
  filename: string;
80
+ type: "file";
81
81
  name?: string | undefined;
82
82
  }>, z.ZodObject<{
83
83
  type: z.ZodLiteral<"dir">;
@@ -103,8 +103,8 @@ declare const zJixoConfig: z.ZodObject<{
103
103
  }>]>]>;
104
104
  }, "strip", z.ZodTypeAny, {
105
105
  tasks: string | {
106
- type: "file";
107
106
  filename: string;
107
+ type: "file";
108
108
  name?: string | undefined;
109
109
  } | {
110
110
  type: "dir";
@@ -114,8 +114,8 @@ declare const zJixoConfig: z.ZodObject<{
114
114
  content: string;
115
115
  name?: string | undefined;
116
116
  } | (string | {
117
- type: "file";
118
117
  filename: string;
118
+ type: "file";
119
119
  name?: string | undefined;
120
120
  } | {
121
121
  type: "dir";
@@ -127,8 +127,8 @@ declare const zJixoConfig: z.ZodObject<{
127
127
  })[];
128
128
  }, {
129
129
  tasks: string | {
130
- type: "file";
131
130
  filename: string;
131
+ type: "file";
132
132
  name?: string | undefined;
133
133
  } | {
134
134
  type: "dir";
@@ -138,8 +138,8 @@ declare const zJixoConfig: z.ZodObject<{
138
138
  content: string;
139
139
  name?: string | undefined;
140
140
  } | (string | {
141
- type: "file";
142
141
  filename: string;
142
+ type: "file";
143
143
  name?: string | undefined;
144
144
  } | {
145
145
  type: "dir";
@@ -154,8 +154,8 @@ export type JixoTask = z.output<typeof zJixoTask>;
154
154
  export type JixoConfig = z.output<typeof zJixoConfig>;
155
155
  export declare const defineConfig: (config: Partial<JixoConfig>) => {
156
156
  tasks: string | {
157
- type: "file";
158
157
  filename: string;
158
+ type: "file";
159
159
  name?: string | undefined;
160
160
  } | {
161
161
  type: "dir";
@@ -165,8 +165,8 @@ export declare const defineConfig: (config: Partial<JixoConfig>) => {
165
165
  content: string;
166
166
  name?: string | undefined;
167
167
  } | (string | {
168
- type: "file";
169
168
  filename: string;
169
+ type: "file";
170
170
  name?: string | undefined;
171
171
  } | {
172
172
  type: "dir";
@@ -179,8 +179,8 @@ export declare const defineConfig: (config: Partial<JixoConfig>) => {
179
179
  };
180
180
  export declare const loadConfig: (dir: string) => Promise<{
181
181
  tasks: string | {
182
- type: "file";
183
182
  filename: string;
183
+ type: "file";
184
184
  name?: string | undefined;
185
185
  } | {
186
186
  type: "dir";
@@ -190,8 +190,8 @@ export declare const loadConfig: (dir: string) => Promise<{
190
190
  content: string;
191
191
  name?: string | undefined;
192
192
  } | (string | {
193
- type: "file";
194
193
  filename: string;
194
+ type: "file";
195
195
  name?: string | undefined;
196
196
  } | {
197
197
  type: "dir";
@@ -0,0 +1,3 @@
1
+ import { type Spinner } from "@gaubee/nodekit";
2
+ export declare const handleRetryError: (error: unknown, loading: Spinner) => Promise<void>;
3
+ //# sourceMappingURL=ai-retry-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-retry-error.d.ts","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAK3D,eAAO,MAAM,gBAAgB,GAAU,OAAO,OAAO,EAAE,SAAS,OAAO,kBA6CtE,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { gray, yellow } from "@gaubee/nodekit";
2
+ import { delay, str_trim_indent } from "@gaubee/util";
3
+ import { APICallError, RetryError } from "ai";
4
+ import ms from "ms";
5
+ import z from "zod";
6
+ export const handleRetryError = async (error, loading) => {
7
+ if (!RetryError.isInstance(error)) {
8
+ return;
9
+ }
10
+ for (const inner_error of error.errors) {
11
+ if (!APICallError.isInstance(inner_error)) {
12
+ continue;
13
+ }
14
+ if (!inner_error.isRetryable) {
15
+ continue;
16
+ }
17
+ try {
18
+ const response = errorSchema.parse(JSON.parse(inner_error.responseBody ?? "{}"));
19
+ const retryDetail = response.error.details.find((d) => "retryDelay" in d);
20
+ if (retryDetail) {
21
+ const retryDelay = ms(retryDetail.retryDelay);
22
+ if (typeof retryDelay === "number") {
23
+ const { prefixText, text } = loading;
24
+ let remainingDelay = retryDelay;
25
+ const tickInterval = 1000;
26
+ const tick = () => {
27
+ loading.prefixText = "⏲️ ";
28
+ loading.text = str_trim_indent(`
29
+ ${yellow(inner_error.message)}
30
+ ${" " + gray("─".repeat(Math.max(4, process.stdout.columns - 2)))}
31
+ Retrying in ${ms(remainingDelay)}...`);
32
+ remainingDelay -= tickInterval;
33
+ };
34
+ tick();
35
+ const ti = setInterval(tick, tickInterval);
36
+ await delay(retryDelay);
37
+ clearInterval(ti);
38
+ // 回滚
39
+ loading.prefixText = prefixText;
40
+ loading.text = text;
41
+ }
42
+ }
43
+ }
44
+ catch {
45
+ console.error("\nQAQ unknown error", error);
46
+ }
47
+ }
48
+ };
49
+ const errorSchema = z.object({
50
+ error: z.object({
51
+ code: z.number(),
52
+ message: z.string(),
53
+ status: z.string(),
54
+ details: z.array(z.union([
55
+ z.object({
56
+ "@type": z.string(),
57
+ violations: z.array(z.object({
58
+ quotaMetric: z.string(),
59
+ quotaId: z.string(),
60
+ quotaDimensions: z.object({
61
+ location: z.string(),
62
+ model: z.string(),
63
+ }),
64
+ quotaValue: z.string(),
65
+ })),
66
+ }),
67
+ z.object({
68
+ "@type": z.string(),
69
+ links: z.array(z.object({ description: z.string(), url: z.string() })),
70
+ }),
71
+ z.object({ "@type": z.string(), retryDelay: z.string() }),
72
+ ])),
73
+ }),
74
+ });
75
+ //# sourceMappingURL=ai-retry-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-retry-error.js","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"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","sourcesContent":["import {gray, yellow, type Spinner} from \"@gaubee/nodekit\";\r\nimport {delay, str_trim_indent} from \"@gaubee/util\";\r\nimport {APICallError, RetryError} from \"ai\";\r\nimport ms from \"ms\";\r\nimport z from \"zod\";\r\nexport const handleRetryError = async (error: unknown, loading: Spinner) => {\r\n if (!RetryError.isInstance(error)) {\r\n return;\r\n }\r\n for (const inner_error of error.errors) {\r\n if (!APICallError.isInstance(inner_error)) {\r\n continue;\r\n }\r\n if (!inner_error.isRetryable) {\r\n continue;\r\n }\r\n\r\n try {\r\n const response = errorSchema.parse(JSON.parse(inner_error.responseBody ?? \"{}\"));\r\n const retryDetail = response.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 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 = str_trim_indent(`\r\n ${yellow(inner_error.message)}\r\n ${\" \" + gray(\"─\".repeat(Math.max(4, process.stdout.columns - 2)))}\r\n Retrying in ${ms(remainingDelay)}...`);\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 }\r\n } catch {\r\n console.error(\"\\nQAQ unknown error\", error);\r\n }\r\n }\r\n};\r\n\r\nconst errorSchema = 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"]}
@@ -0,0 +1,2 @@
1
+ export declare const parseProgress: (p: unknown) => number;
2
+ //# sourceMappingURL=parse-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-progress.d.ts","sourceRoot":"","sources":["../../src/helper/parse-progress.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,GAAI,GAAG,OAAO,WAuBvC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { math_clamp } from "@gaubee/util";
2
+ export const parseProgress = (p) => {
3
+ let progress = 0;
4
+ switch (typeof p) {
5
+ case "number": {
6
+ progress = p;
7
+ break;
8
+ }
9
+ case "string": {
10
+ const p_str = p.trim();
11
+ if (p_str.endsWith("%")) {
12
+ progress = +p_str.slice(0, -1) / 100;
13
+ }
14
+ else {
15
+ progress = +p_str;
16
+ }
17
+ break;
18
+ }
19
+ }
20
+ if (Number.isFinite(progress)) {
21
+ progress = math_clamp(progress, 0, 1);
22
+ }
23
+ else {
24
+ progress = 0;
25
+ }
26
+ return progress;
27
+ };
28
+ //# sourceMappingURL=parse-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-progress.js","sourceRoot":"","sources":["../../src/helper/parse-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAU,EAAE,EAAE;IAC1C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,QAAQ,OAAO,CAAC,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACvB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,QAAQ,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,CAAC,KAAK,CAAC;YACpB,CAAC;YACD,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,CAAC,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC","sourcesContent":["import {math_clamp} from \"@gaubee/util\";\n\nexport const parseProgress = (p: unknown) => {\n let progress = 0;\n switch (typeof p) {\n case \"number\": {\n progress = p;\n break;\n }\n case \"string\": {\n const p_str = p.trim();\n if (p_str.endsWith(\"%\")) {\n progress = +p_str.slice(0, -1) / 100;\n } else {\n progress = +p_str;\n }\n break;\n }\n }\n if (Number.isFinite(progress)) {\n progress = math_clamp(progress, 0, 1);\n } else {\n progress = 0;\n }\n return progress;\n};\n"]}
@@ -20,6 +20,9 @@ export declare const resolveAiTasks: (cwd: string, config_tasks: JixoConfig["tas
20
20
  useLog: string;
21
21
  log: string;
22
22
  startTime: string;
23
+ createTime: string;
24
+ preUpdateTime: string;
25
+ preProgress: number;
23
26
  })[];
24
27
  export type AiTask = ReturnType<typeof resolveAiTasks>[number];
25
28
  //# sourceMappingURL=resolve-ai-tasks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ai-tasks.d.ts","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,cAAc,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,cAAc,UAAU,CAAC,OAAO,CAAC;UAGnE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC;aACjB,MAAM;;UAGT,MAAM;SACP,MAAM;UACL,MAAM,EAAE;YACN,MAAM,EAAE;WACT,MAAM;eACF,MAAM;YACT,MAAM;SACT,MAAM;eACA,MAAM;IAwGpB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"resolve-ai-tasks.d.ts","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"AAMA,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,cAAc,CAAC;AAG7C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,cAAc,UAAU,CAAC,OAAO,CAAC;UAGnE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC;aACjB,MAAM;;UAGT,MAAM;SACP,MAAM;UACL,MAAM,EAAE;YACN,MAAM,EAAE;WACT,MAAM;eACF,MAAM;YACT,MAAM;SACT,MAAM;eACA,MAAM;gBACL,MAAM;mBACH,MAAM;iBACR,MAAM;IA+HtB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,9 +1,11 @@
1
1
  import { matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown } from "@gaubee/nodekit";
2
+ import { str_trim_indent } from "@gaubee/util";
2
3
  import fs from "node:fs";
3
4
  import path from "node:path";
4
5
  import { match, P } from "ts-pattern";
5
6
  import z from "zod";
6
7
  import {} from "../config.js";
8
+ import { parseProgress } from "./parse-progress.js";
7
9
  /**
8
10
  * 将 config.tasks 字段转化成具体的 ai-tasks 信息
9
11
  * @param cwd
@@ -28,12 +30,28 @@ export const resolveAiTasks = (cwd, config_tasks) => {
28
30
  const useMemory = ai_task.data.useMemory || task_name;
29
31
  const useLog = ai_task.data.useLog || task_name;
30
32
  const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);
31
- if (!fs.existsSync(log_filepath)) {
32
- writeMarkdown(log_filepath, ``, {
33
+ let log_fileContent = fs.existsSync(log_filepath) ? fs.readFileSync(log_filepath, "utf-8").trim() : "";
34
+ if (log_fileContent === "") {
35
+ writeMarkdown(log_filepath, str_trim_indent(`
36
+ ## 工作计划
37
+
38
+ <!--待定-->
39
+
40
+ ---
41
+
42
+ ## 工作日志
43
+
44
+ <!--暂无-->
45
+ `), {
46
+ title: "_待定_",
33
47
  createTime: new Date().toISOString(),
34
48
  updateTime: new Date().toISOString(),
49
+ progress: "0%",
35
50
  });
51
+ log_fileContent = fs.readFileSync(log_filepath, "utf-8");
36
52
  }
53
+ const log_fileData = matter(log_fileContent).data;
54
+ const startTime = new Date().toISOString();
37
55
  tasks.push({
38
56
  ...ai_task,
39
57
  name: task_name,
@@ -49,8 +67,11 @@ export const resolveAiTasks = (cwd, config_tasks) => {
49
67
  .otherwise(() => ""),
50
68
  useMemory,
51
69
  useLog,
52
- log: fs.readFileSync(log_filepath, "utf-8"),
53
- startTime: new Date().toISOString(),
70
+ createTime: log_fileData.createTime ?? startTime,
71
+ preUpdateTime: log_fileData.updateTime ?? startTime,
72
+ preProgress: parseProgress(log_fileData.progress),
73
+ log: log_fileContent,
74
+ startTime: startTime,
54
75
  });
55
76
  };
56
77
  for (const config_task of config_tasks_arr) {
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ai-tasks.js","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import {matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown} from \"@gaubee/nodekit\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {match, P} from \"ts-pattern\";\nimport z from \"zod\";\nimport {type JixoConfig} from \"../config.js\";\n\n/**\n * 将 config.tasks 字段转化成具体的 ai-tasks 信息\n * @param cwd\n * @param config_tasks\n * @returns\n */\nexport const resolveAiTasks = (cwd: string, config_tasks: JixoConfig[\"tasks\"]) => {\n const config_tasks_arr = Array.isArray(config_tasks) ? config_tasks : [config_tasks];\n type TaskBase = {\n data: {[key: string]: any};\n content: string;\n };\n type AiTask = TaskBase & {\n name: string;\n cwd: string;\n dirs: string[];\n agents: string[];\n model: string;\n useMemory: string;\n useLog: string;\n log: string;\n startTime: string;\n };\n const tasks: AiTask[] = [];\n const addTask = (\n ai_task: TaskBase,\n options: {\n defaultName: string;\n },\n ) => {\n const {name: inner_task_name} = ai_task.data;\n\n const task_dir = match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.dirs ?? ai_task.data.dir))\n .with({success: true}, (it) => {\n const dirList = Array.isArray(it.data) ? it.data : [it.data];\n return dirList.map((dir) => normalizeFilePath(path.resolve(cwd, dir)));\n })\n .otherwise(() => []);\n if (task_dir.length === 0) {\n task_dir.push(cwd);\n }\n\n const task_name = inner_task_name || options.defaultName;\n const useMemory = ai_task.data.useMemory || task_name;\n const useLog = ai_task.data.useLog || task_name;\n\n const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);\n if (!fs.existsSync(log_filepath)) {\n writeMarkdown(log_filepath, ``, {\n createTime: new Date().toISOString(),\n updateTime: new Date().toISOString(),\n });\n }\n\n tasks.push({\n ...ai_task,\n name: task_name,\n cwd: cwd,\n dirs: task_dir,\n agents: match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.agents))\n .with({success: true, data: P.select()}, (agents) => {\n return Array.isArray(agents) ? agents : agents.split(/\\s+/);\n })\n .otherwise(() => []),\n model: match(z.string().safeParse(ai_task.data.model))\n .with({success: true, data: P.select()}, (model) => model)\n .otherwise(() => \"\"),\n useMemory,\n useLog,\n log: fs.readFileSync(log_filepath, \"utf-8\"),\n startTime: new Date().toISOString(),\n });\n };\n\n for (const config_task of config_tasks_arr) {\n match(config_task)\n .with(\n {\n type: \"dir\",\n dirname: P.string.select(),\n },\n (dirname) => {\n for (const entry of walkFiles(path.resolve(cwd, dirname), {\n matchFile(entry) {\n return entry.name.endsWith(\".task.md\");\n },\n })) {\n addTask(readMarkdown(entry.path), {\n defaultName: entry.name.slice(0, -\".task.md\".length),\n });\n }\n },\n )\n .with(\n {\n type: \"file\",\n filename: P.string.select(\"filename\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(readMarkdown(m.filename), {\n defaultName: m.name ?? m.filename.slice(0, -\".task.md\".length),\n });\n },\n )\n .with(P.string.select(), (mdContent) => {\n addTask(matter(mdContent), {\n defaultName: `${tasks.length + 1}`,\n });\n })\n .with(\n {\n type: \"prompt\",\n content: P.string.select(\"content\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(matter(m.content), {\n defaultName: m.name ?? `${tasks.length + 1}`,\n });\n },\n )\n .exhaustive();\n }\n return tasks;\n};\n\nexport type AiTask = ReturnType<typeof resolveAiTasks>[number];\n"]}
1
+ {"version":3,"file":"resolve-ai-tasks.js","sourceRoot":"","sources":["../../src/helper/resolve-ai-tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import {matter, normalizeFilePath, readMarkdown, walkFiles, writeMarkdown} from \"@gaubee/nodekit\";\nimport {str_trim_indent} from \"@gaubee/util\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {match, P} from \"ts-pattern\";\nimport z from \"zod\";\nimport {type JixoConfig} from \"../config.js\";\nimport {parseProgress} from \"./parse-progress.js\";\n\n/**\n * 将 config.tasks 字段转化成具体的 ai-tasks 信息\n * @param cwd\n * @param config_tasks\n * @returns\n */\nexport const resolveAiTasks = (cwd: string, config_tasks: JixoConfig[\"tasks\"]) => {\n const config_tasks_arr = Array.isArray(config_tasks) ? config_tasks : [config_tasks];\n type TaskBase = {\n data: {[key: string]: any};\n content: string;\n };\n type AiTask = TaskBase & {\n name: string;\n cwd: string;\n dirs: string[];\n agents: string[];\n model: string;\n useMemory: string;\n useLog: string;\n log: string;\n startTime: string;\n createTime: string;\n preUpdateTime: string;\n preProgress: number;\n };\n const tasks: AiTask[] = [];\n const addTask = (\n ai_task: TaskBase,\n options: {\n defaultName: string;\n },\n ) => {\n const {name: inner_task_name} = ai_task.data;\n\n const task_dir = match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.dirs ?? ai_task.data.dir))\n .with({success: true}, (it) => {\n const dirList = Array.isArray(it.data) ? it.data : [it.data];\n return dirList.map((dir) => normalizeFilePath(path.resolve(cwd, dir)));\n })\n .otherwise(() => []);\n if (task_dir.length === 0) {\n task_dir.push(cwd);\n }\n\n const task_name = inner_task_name || options.defaultName;\n const useMemory = ai_task.data.useMemory || task_name;\n const useLog = ai_task.data.useLog || task_name;\n\n const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);\n let log_fileContent = fs.existsSync(log_filepath) ? fs.readFileSync(log_filepath, \"utf-8\").trim() : \"\";\n if (log_fileContent === \"\") {\n writeMarkdown(\n log_filepath,\n str_trim_indent(`\n ## 工作计划\n \n <!--待定-->\n\n ---\n\n ## 工作日志\n\n <!--暂无-->\n `),\n {\n title: \"_待定_\",\n createTime: new Date().toISOString(),\n updateTime: new Date().toISOString(),\n progress: \"0%\",\n },\n );\n log_fileContent = fs.readFileSync(log_filepath, \"utf-8\");\n }\n const log_fileData = matter(log_fileContent).data;\n const startTime = new Date().toISOString();\n\n tasks.push({\n ...ai_task,\n name: task_name,\n cwd: cwd,\n dirs: task_dir,\n agents: match(z.union([z.string(), z.string().array()]).safeParse(ai_task.data.agents))\n .with({success: true, data: P.select()}, (agents) => {\n return Array.isArray(agents) ? agents : agents.split(/\\s+/);\n })\n .otherwise(() => []),\n model: match(z.string().safeParse(ai_task.data.model))\n .with({success: true, data: P.select()}, (model) => model)\n .otherwise(() => \"\"),\n useMemory,\n useLog,\n createTime: log_fileData.createTime ?? startTime,\n preUpdateTime: log_fileData.updateTime ?? startTime,\n preProgress: parseProgress(log_fileData.progress),\n log: log_fileContent,\n startTime: startTime,\n });\n };\n\n for (const config_task of config_tasks_arr) {\n match(config_task)\n .with(\n {\n type: \"dir\",\n dirname: P.string.select(),\n },\n (dirname) => {\n for (const entry of walkFiles(path.resolve(cwd, dirname), {\n matchFile(entry) {\n return entry.name.endsWith(\".task.md\");\n },\n })) {\n addTask(readMarkdown(entry.path), {\n defaultName: entry.name.slice(0, -\".task.md\".length),\n });\n }\n },\n )\n .with(\n {\n type: \"file\",\n filename: P.string.select(\"filename\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(readMarkdown(m.filename), {\n defaultName: m.name ?? m.filename.slice(0, -\".task.md\".length),\n });\n },\n )\n .with(P.string.select(), (mdContent) => {\n addTask(matter(mdContent), {\n defaultName: `${tasks.length + 1}`,\n });\n })\n .with(\n {\n type: \"prompt\",\n content: P.string.select(\"content\"),\n name: P.string.select(\"name\").optional(),\n },\n (m) => {\n addTask(matter(m.content), {\n defaultName: m.name ?? `${tasks.length + 1}`,\n });\n },\n )\n .exhaustive();\n }\n return tasks;\n};\n\nexport type AiTask = ReturnType<typeof resolveAiTasks>[number];\n"]}