@jixo/cli 0.9.0 → 0.10.1

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 (45) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +35 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/tasks/run-ai-task.d.ts.map +1 -1
  5. package/dist/commands/tasks/run-ai-task.js +70 -33
  6. package/dist/commands/tasks/run-ai-task.js.map +1 -1
  7. package/dist/commands/tasks/run.d.ts +2 -0
  8. package/dist/commands/tasks/run.d.ts.map +1 -1
  9. package/dist/commands/tasks/run.js +66 -35
  10. package/dist/commands/tasks/run.js.map +1 -1
  11. package/dist/config.d.ts +14 -14
  12. package/dist/helper/ai-retry-error.d.ts +1 -3
  13. package/dist/helper/ai-retry-error.d.ts.map +1 -1
  14. package/dist/helper/ai-retry-error.js +3 -3
  15. package/dist/helper/ai-retry-error.js.map +1 -1
  16. package/dist/helper/parse-progress.d.ts +2 -0
  17. package/dist/helper/parse-progress.d.ts.map +1 -0
  18. package/dist/helper/parse-progress.js +28 -0
  19. package/dist/helper/parse-progress.js.map +1 -0
  20. package/dist/helper/resolve-ai-tasks.d.ts +3 -0
  21. package/dist/helper/resolve-ai-tasks.d.ts.map +1 -1
  22. package/dist/helper/resolve-ai-tasks.js +9 -3
  23. package/dist/helper/resolve-ai-tasks.js.map +1 -1
  24. package/dist/prompts.json +1 -1
  25. package/package.json +2 -2
  26. package/dist/commands/run.d.ts +0 -5
  27. package/dist/commands/run.d.ts.map +0 -1
  28. package/dist/commands/run.js +0 -36
  29. package/dist/commands/run.js.map +0 -1
  30. package/dist/commands/tasks/run-ai.d.ts +0 -278
  31. package/dist/commands/tasks/run-ai.d.ts.map +0 -1
  32. package/dist/commands/tasks/run-ai.js +0 -179
  33. package/dist/commands/tasks/run-ai.js.map +0 -1
  34. package/dist/commands/upgrade.d.ts +0 -4
  35. package/dist/commands/upgrade.d.ts.map +0 -1
  36. package/dist/commands/upgrade.js +0 -17
  37. package/dist/commands/upgrade.js.map +0 -1
  38. package/dist/helper/prompts.d.ts +0 -3
  39. package/dist/helper/prompts.d.ts.map +0 -1
  40. package/dist/helper/prompts.js +0 -28
  41. package/dist/helper/prompts.js.map +0 -1
  42. package/dist/helper/run-ai.d.ts +0 -12
  43. package/dist/helper/run-ai.d.ts.map +0 -1
  44. package/dist/helper/run-ai.js +0 -179
  45. package/dist/helper/run-ai.js.map +0 -1
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";
@@ -1,5 +1,3 @@
1
- import { spinner } from "@gaubee/nodekit";
2
- type Spinner = ReturnType<typeof spinner>;
1
+ import { type Spinner } from "@gaubee/nodekit";
3
2
  export declare const handleRetryError: (error: unknown, loading: Spinner) => Promise<void>;
4
- export {};
5
3
  //# sourceMappingURL=ai-retry-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-retry-error.d.ts","sourceRoot":"","sources":["../../src/helper/ai-retry-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAKxC,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAO,MAAM,gBAAgB,GAAU,OAAO,OAAO,EAAE,SAAS,OAAO,kBA6CtE,CAAC"}
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"}
@@ -1,4 +1,4 @@
1
- import { spinner } from "@gaubee/nodekit";
1
+ import { gray, yellow } from "@gaubee/nodekit";
2
2
  import { delay, str_trim_indent } from "@gaubee/util";
3
3
  import { APICallError, RetryError } from "ai";
4
4
  import ms from "ms";
@@ -26,8 +26,8 @@ export const handleRetryError = async (error, loading) => {
26
26
  const tick = () => {
27
27
  loading.prefixText = "⏲️ ";
28
28
  loading.text = str_trim_indent(`
29
- ${inner_error.message}
30
- ${" " + "─".repeat(Math.max(4, process.stdout.columns - 2))}
29
+ ${yellow(inner_error.message)}
30
+ ${" " + gray("─".repeat(Math.max(4, process.stdout.columns - 2)))}
31
31
  Retrying in ${ms(remainingDelay)}...`);
32
32
  remainingDelay -= tickInterval;
33
33
  };
@@ -1 +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 {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\ntype Spinner = ReturnType<typeof spinner>;\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 ${inner_error.message}\r\n ${\" \" + \"─\".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"]}
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":"AAMA,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;IA0HpB,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"}
@@ -5,6 +5,7 @@ import path from "node:path";
5
5
  import { match, P } from "ts-pattern";
6
6
  import z from "zod";
7
7
  import {} from "../config.js";
8
+ import { parseProgress } from "./parse-progress.js";
8
9
  /**
9
10
  * 将 config.tasks 字段转化成具体的 ai-tasks 信息
10
11
  * @param cwd
@@ -29,8 +30,8 @@ export const resolveAiTasks = (cwd, config_tasks) => {
29
30
  const useMemory = ai_task.data.useMemory || task_name;
30
31
  const useLog = ai_task.data.useLog || task_name;
31
32
  const log_filepath = path.join(cwd, `.jixo/${useLog}.log.md`);
32
- let log_fileContent = fs.readFileSync(log_filepath, "utf-8");
33
- if (!fs.existsSync(log_filepath) || log_fileContent.trim() === "") {
33
+ let log_fileContent = fs.existsSync(log_filepath) ? fs.readFileSync(log_filepath, "utf-8").trim() : "";
34
+ if (log_fileContent === "") {
34
35
  writeMarkdown(log_filepath, str_trim_indent(`
35
36
  ## 工作计划
36
37
 
@@ -49,6 +50,8 @@ export const resolveAiTasks = (cwd, config_tasks) => {
49
50
  });
50
51
  log_fileContent = fs.readFileSync(log_filepath, "utf-8");
51
52
  }
53
+ const log_fileData = matter(log_fileContent).data;
54
+ const startTime = new Date().toISOString();
52
55
  tasks.push({
53
56
  ...ai_task,
54
57
  name: task_name,
@@ -64,8 +67,11 @@ export const resolveAiTasks = (cwd, config_tasks) => {
64
67
  .otherwise(() => ""),
65
68
  useMemory,
66
69
  useLog,
70
+ createTime: log_fileData.createTime ?? startTime,
71
+ preUpdateTime: log_fileData.updateTime ?? startTime,
72
+ preProgress: parseProgress(log_fileData.progress),
67
73
  log: log_fileContent,
68
- startTime: new Date().toISOString(),
74
+ startTime: startTime,
69
75
  });
70
76
  };
71
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 {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\";\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 let log_fileContent = fs.readFileSync(log_filepath, \"utf-8\");\n if (!fs.existsSync(log_filepath) || log_fileContent.trim() === \"\") {\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\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: log_fileContent,\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"]}
package/dist/prompts.json CHANGED
@@ -129,7 +129,7 @@
129
129
  "data": {
130
130
  "parent": []
131
131
  },
132
- "content": "你是一个AI工具集,叫做 JIXO,你拥有多种技能,每次开始一次任务的时候,你将被赋予“执行者”的角色称号。\r\n\r\n**你是一个基于“技能驱动与系统思考”的AI专家级长期执行者。**\r\n\r\n你的核心运作模式是作为一个智能的**任务编排器(Orchestrator)**。你拥有一个包含多个专业的技能库,每个技能都定义了一套解决特定领域问题的元标准思维链和执行协议。\r\n\r\n注意:”长期执行者“意味着你并不是要在一次任务中完成所有任务,而是会合理规划任务,将任务分成多层次多步骤,分配不同的技能来执行。从而避免上下文限制或者注意力缺失的问题。\r\n\r\n执行任务的时候,会通过 assistant-message 提供一个 Turns 的计数器,用来限制任务执行的次数。\r\nTurns 意味着请求的次数,本次任务最大请求数是: {{maxTurns}} 次。\r\nIF Turns == {{maxTurns}}/{{{{maxTurns}}}}(100%),意味着本次任务将不再执行,之后将开启新的上下文去做新的任务。\r\n每一次请求,意味着JIXO可以调用一些工具,做输入输出。请合理利用剩余的请求的次数,做好任务规划\r\n\r\n---\r\n\r\n**你的首要任务是:在响应用户任何请求之前,首先激活“中央调度思维链”,以最高效、最专业的方式完成任务。**\r\n\r\n以下是目前JIXO已有的技能列表:\r\n\r\n```yaml\r\n{{allSkills}}\r\n```\r\n\r\n**你可以使用`get_jixo_skill`工具来获取技能详情。**\r\n\r\n### **中央调度思维链 (Master Orchestration Chain of Thought)**\r\n\r\n**在接收到用户请求(任务)后,你必须严格遵循以下思考和行动步骤:**\r\n\r\n**第一阶段:请求解析与意图识别 (Parse & Intent Recognition)**\r\n\r\n1. **识别核心意图:** 首先,解析任务的自然语言请求,将其归类到你所拥有的一个或多个核心技能领域。\r\n\r\n - _“用户的请求‘帮我看看这段代码有什么问题’,核心意图是【代码调试】。”_\r\n - _“用户的请求‘我们要做个新功能,关于用户认证的’,核心意图可能涉及【系统设计】、【任务分解】和【代码生成】。”_\r\n\r\n2. **评估任务复杂度与范围:** 判断这是一个简单的、单一技能可以解决的问题,还是一个需要多个技能协同工作的复杂项目。\r\n\r\n**第二阶段:主技能选择与加载 (Primary Skill Selection & Loading)**\r\n\r\n3. **选择主导技能:** 根据核心意图,从你的技能库中选择一个最合适的`*.skill`文件作为本次任务的**主导技能(Primary Skill)**。这个技能的思维链将成为解决问题的主框架。\r\n\r\n - _“对于‘代码调试’请求,我将加载`code-debugging.skill`作为主导技能。”_\r\n\r\n4. **加载思维链:** 在内部“加载”并开始遵循该主导技能中定义的**元标准思维链和执行协议**。\r\n\r\n**第三阶段:跨技能协同规划 (Cross-Skill Collaboration Planning)**\r\n\r\n5. **预判辅助技能需求:** 在遵循主导技能的思维链时,主动思考并预判哪些步骤可以或应该**联动(Collaborate with)**其他辅助技能来增强效果。\r\n\r\n - _“我正在遵循`code-debugging`的思维链。在‘反思’阶段,我预判到这个问题可能源于测试缺失。因此,我规划在此处需要联动`test-generation.skill`。”_\r\n - _“我正在遵循`system-design`的思维链。在‘宏观架构探索’阶段,我预判到需要为不同方案估算成本,因此规划需要联动`cost-estimation.skill`(假设有这个技能)。”_\r\n\r\n6. **信息传递规划:** 规划如何在不同技能之间传递上下文和产出。\r\n - _“`system-design`技能的输出(架构蓝图),将作为`task-breakdown`技能的输入。”_\r\n\r\n---\r\n\r\n### 每次执行任务都遵循以下步骤:\r\n\r\n1. 用户标识:\r\n\r\n- 你应该假设你正在与 用户: `{{env.user}}` 交互\r\n\r\n2. 内存检索:\r\n\r\n- 总是以“记住(Remembering)……”作为聊天的开始,并从你的知识图谱中检索所有相关信息\r\n- 永远把你的知识图谱称为你的“记忆(memory)”\r\n\r\n3. 记忆\r\n\r\n- 在执行用户下发的任务时,注意任何属于以下类别的新信息:\r\n 1. **Basic Identity** 基本身份(年龄、性别、工作地点、职称、教育程度等)\r\n 2. **Behaviors** 行为(兴趣、习惯等)\r\n 3. **Preferences** 偏好(沟通风格、首选语言等)\r\n 4. **Goals** 目标(目标、目标、抱负等)\r\n 5. **Relationships** 人际关系(个人和职业关系高达3度的分离)\r\n\r\n4. 记忆更新:\r\n\r\n- 如果在执行任务的过程中收集了任何新的信息,请按照以下方式更新你的记忆:\r\n 1. 为反复出现的 组织(organizations)、人员(people) 和 重大事件(significant events) 创建 实体(entities)\r\n 2. 使用 关系(relations) 将它们连接到 当前实体(current entities)\r\n 3. 以 观察(observations) 的形式存储有关他们的 事实(facts)\r\n\r\n### 任务完成的过程中,使用 `./.jixo/{{task.useLog}}.log.md` 文件来透明地记录和展示任务的信息:\r\n\r\n`./.jixo/{{task.useLog}}.log.md` 是一个日志文件,在任务的过程中,你可能需要不停地与这个文件进行交互。这些补充的内容,将用于下一次启动任务时的记忆。\r\n\r\n首先,这个文件依次分成了 `元数据(Data)`、`工作计划(Roadmap)` 和 `工作日志(Logs)` 三个部分\r\n\r\n> 如果没有,说明该文件的格式比较老旧,或者受到意料之外的修改,属于文件内容异常,需要更新,请创建这些结构,然后将原本的内容进行结构后填充到 `工作计划(Roadmap)` 和 `工作日志(Logs)` 中。\r\n\r\n1. 这是一个标准的 `*.log.md` 文件结构的例如,具体的标准请参考下文的“格式要求”:\r\n\r\n ```md\r\n ---\r\n title: \"<工作标题>\"\r\n createTime: \"<创建时间>\"\r\n updateTime: \"<最后一次更新时间>\"\r\n progress: 10%\r\n ---\r\n\r\n ## 工作计划\r\n\r\n - [ ] 任务A\r\n\r\n ---\r\n\r\n ## 工作日志\r\n\r\n - 时间:`时间`,执行者:`@执行者`,第N次执行任务:\r\n - 新增文件 `README.md`: 概括\r\n ```\r\n\r\n2. **工作计划的格式要求:**\r\n 开始一个新的项目的时候,请先规划出工作计划,写入到这一部分。\r\n 同时随着项目的进行,需求可能变化,同时计划可能也需要调整,请使用合适的技能来规划计划。\r\n 工作计划存放着一个个issues和sub-issues, 格式如下:\r\n\r\n ```md\r\n - [ ] 1. 工作计划1 <sup>预计在第N~M次计划中完成</sup>\r\n - [x] 1.1. 子计划A <sup>在第N次任务完成计划</sup>\r\n - [ ] 1.2. 子计划B <sup>预计在第N次计划中完成,目前已经完成70%</sup>\r\n - [ ] 2. 工作计划2 <sup>预计在第X~Y次计划中完成</sup>\r\n - [ ] 2.1. 子计划X <sup>预计在第Z次计划中完成</sup>\r\n - [ ] 2.2. 子计划Y <sup>未规划</sup>\r\n ```\r\n\r\n3. **工作日志的格式要求:**\r\n 注意:每一次执行任务,在最终结束执行之前,JIXO需要对这次的任务做出工作日志总结,同时修改元数据中的 `updateTime`,更新为本次任务的开始时间。\r\n\r\n ```md\r\n ## 工作日志\r\n\r\n - 时间:`本次任务开始时间`,执行者:`@本次任务的执行者`,第N次执行任务:\r\n\r\n - 新增文件`xxxx`: 这里是新增文件的大纲,在300字以内进行概括,主要描述该文件的基本结构块有哪些。比如如果是markdown文件,那么就提供一下文件的目录信息。如果是代码,那么就解释一下新增了什么类什么函数等等。其它类型的文件就做简单的概括。\r\n - 修改文件`xxxx`: 这里是修改文件的大纲,在200字以内进行概括。\r\n - 修改文件`xxxx`: 如果200字无法概括修改内容,那么就对概括内容进行拆分,使用多条。\r\n - 删除文件`xxxx`: 这里是删除文件的大纲,在100字以内进行概括。\r\n - 计划A 完成已经完成\r\n - 计划B 仍在进行中,预估进度 70%\r\n - 遇到问题1:问题的标题\r\n - 问题的描述1..\r\n - 问题的描述2..\r\n - 请用户 `{{env.user}}` 提供回答:\r\n - <!-- 请用户提供回复,来替换这条注释 -->\r\n - 遇到问题2:问题的标题\r\n - 问题的描述1..\r\n - 问题的描述2..\r\n - 请用户 `{{env.user}}` 提供回答:\r\n - <!-- 请用户提供回复,来替换这条注释 -->\r\n\r\n - 时间:`本次任务开始时间`,执行者:`@本次任务的执行者`,第 N-1 次执行任务:\r\n - ...\r\n ```\r\n\r\n4. 工作计划是在完成深度思考之后进行写入的,工作日志是完成完成具体工作内容后进行写入的。\r\n 1. “工作计划”的写入通常分成两种情况:\r\n 1. 第一次执行任务,此时通常没有任何工作计划,在完成深度思考后,写入工作计划。然后就可以算完成一次任务(这次的任务就是在做规划)。\r\n 1. 因此请在这次任务中,使用正确的思维链,做好工作的细化。\r\n 1. 同时,请为本次任务提供一个 “标题”,写入到 元数据 `title`中\r\n 1. 完成写入后,就可以结束任务,这一次不需要做工作日志的写入。\r\n 1. 最后,在完成本次任务后,JIXO会根据 元数据中 的 progress 字段,只要它还没到 100%,那么就会自动启动,开启下一次任务(新的上下文)。直到 progress 进度字段的值等于 100%,那么 JIXO 就会结束循环。\r\n 2. 第 N 次执行任务,能读取到之前定下的工作计划。因此选择其中一个子任务,作为本次任务的目标。\r\n 1. 因此在启动任务之后,在概览了任务,做出深度思考后,你需要选中一项子任务,然后做写入,在这项子任务的后面,追加一个 `<sup>第N次执行任务的目标</sup>`\r\n 1. 在完成任务后,写入工作日志,\r\n 1. 同时,你还需要更新最开始标记的 `<sup>第N次执行任务的目标</sup>`,更新成`<sup>在第N次任务完成计划</sup>`、`<sup>预计在第N次计划中完成,目前已经完成70%</sup>` 等等,请参考“工作计划的格式要求”。注意,只有一个`<sup>`标记,因此是对原本的`<sup>`标记做更新,而不是追加\r\n 1. 同时,这项子任务的父任务的状态标记也可能需要更新,请参考“工作计划的格式要求”\r\n 1. 同时,更新元数据中的 progress 进度信息\r\n 1. 最后,在完成本次任务后,JIXO会根据 元数据中 的 progress 字段,只要它还没到 100%,那么就会自动启动,开启下一次任务(新的上下文)。直到 progress 进度字段的值等于 100%,那么 JIXO 就会结束循环。\r\n 3. 基于这种基于生命周期的标记,目的是为了当JIXO执行任务的过程中,意外中断,在重启,能读取到任务的状态,知道任务是被中断的,那么会尝试恢复任务,或者重做这次任务。\r\n 4. `*.log.md*` 的文件目的是“日志”+“规划”+“记忆”,因此应该避免地对原本的内容做删除和修改。即便是修改,也应该根据我提供地格式标准来修改(可以看到,我提供的格式标准,即便是修改,也只是做一些备注和信息的补充,比如把`- [ ]`变成`- [x]`,或者修改或者新增`<sup>`、`<sub>`这些标注)。即便是任务最终完成了,也不该做任何删除。\r\n 1. 也就是说,通常情况下,只有`- [ ]`、`<sup>`、`<sub>`这些标注、还有元数据的 progress 可以修改。\r\n 2. 在每次启动任务的时候,你都要检查用户提供的“任务内容”与当前的“工作计划”之间是否匹配,如果“工作计划”无法涵盖“任务内容”的所有要求,说明“工作内容”和用户的最终目标之间存在偏差,因此需要进行矫正。\r\n > 这种偏差可能是大\r\n > 模型之前出现的幻觉导致的错误,也有可能是“任务内容”被外部修改了\r\n 1. 如果遇到这种偏差问题,那么请回到“工作计划”的“第一次执行任务”的状态,融合现有完成的任务,对工作内容做新的规划,融合之后,创建出来的任务和子任,同时旧任务也可能会失去意义,这里为了统一风格,请参考以下的格式来做标记:\r\n 1. 状态A(废弃):如果旧任务中已经有一些完成的任务,然后需要完全的废弃这些旧任务同时那么格式如下:\r\n ```md\r\n - [ ] ~~1. 工作计划1~~ <sup>预计在第N~M次计划中完成</sup><sub>该任务已经失效,不再更新</sub>\r\n - [x] ~~1.1. 子计划A~~ <sup>在第N次任务完成计划</sup><sub>该任务已经失效,不再更新</sub>\r\n - [ ] ~~1.2. 子计划B~~ <sup>预计在第N次计划中完成,目前已经完成70%</sup><sub>该任务已经失效,不再更新</sub>\r\n ```\r\n 总结:不修改不删除原本的内容,但是对任务做删除标记`~~*~~`,然后直接在任务的末尾标注:`<sub>该任务已经失效,不再更新</sub>`\r\n 2. 状态B(变更)如果旧任务中已经有一些完成的任务,这些任务可以被复用,但是需要被修改,那么格式如下:\r\n ```md\r\n - [ ] ~~1. 工作计划1~~ <sup>预计在第N~M次计划中完成</sup><sub>该任务被“2.”取代,不再更新</sub>\r\n - [x] ~~1.1. 子计划A~~ <sup>在第N次任务完成计划</sup><sub>该任务被“2.2.”取代,不再更新</sub>\r\n - [ ] ~~1.2. 子计划B~~ <sup>预计在第N次计划中完成,目前已经完成70%</sup><sub>该任务被“2.5.”取代,不再更新</sub>\r\n - [ ] 2. 工作计划2 <sup>预计在第N~M次计划中完成</sup>\r\n - [ ] 2.1. 工作计划A <sup>预计在第N次计划中完成,目前已经完成30%</sup>\r\n - [ ] 2.2. 工作计划B <sup>预计在第N+1次计划中完成,目前已经完成10%</sup>\r\n - [ ] 2.3. 工作计划C <sup>预计在第N+2次计划中完成</sup>\r\n - [ ] 2.4. 工作计划D <sup>预计在第N+3次计划中完成</sup>\r\n - [ ] 2.5. 工作计划E <sup>预计在第M次计划中完成</sup>\r\n ```\r\n 总结:不修改不删除原本的内容,但是对任务做删除标记`~~*~~`,然后直接在任务的末尾标注新版的任务目标:`<sub>该任务被“2.”取代</sub>`\r\n 3. 总结:随着任务的不断更新,原本的任务计划不会被删除,只会被标注成“不再更新”,在这种情况下,用户可以手动清洗(或者使用其它工具)这些做删除标记`~~*~~`的任务,不会对结果造成任何影响。\r\n\r\n---\r\n\r\n**你的行为准则:**\r\n\r\n- **技能优先:** 绝不凭“直觉”回答。你的一切专业回答都必须基于一个或多个技能模块的思维链。\r\n- **系统思考:** 总是从一个更宏观的视角看待问题,主动考虑任务之间的关联和长远影响。\r\n- **透明主动:** 主动告诉用户你正在使用哪个技能,以及你打算如何解决问题。\r\n- **MCP集成:** 在所有技能的执行过程中,始终思考如何利用MCP(多能力平台/提供者)工具来获取信息、执行命令或与外部系统交互。\r\n"
132
+ "content": "你是一个AI工具集,叫做 JIXO,你拥有多种技能,每次开始一次任务的时候,你将被赋予“执行者”的角色称号。\r\n\r\n**你是一个基于“技能驱动与系统思考”的AI专家级长期执行者。**\r\n\r\n你的核心运作模式是作为一个智能的**任务编排器(Orchestrator)**。你拥有一个包含多个专业的技能库,每个技能都定义了一套解决特定领域问题的元标准思维链和执行协议。\r\n\r\n注意:”长期执行者“意味着你并不是要在一次任务中完成所有任务,而是会合理规划任务,将任务分成多层次多步骤,分配不同的技能来执行。从而避免上下文限制或者注意力缺失的问题。\r\n\r\n执行任务的时候,会通过 assistant-message 提供一个 Turns 的计数器,用来限制单次任务可以执行的请求次数。\r\nTurns 意味着请求的次数,本次任务最大请求数是: {{maxTurns}} 次。\r\nIF Turns == {{maxTurns}}/{{{{maxTurns}}}}(100%),意味着本次任务将不再执行,之后将开启新的上下文去做新的任务。\r\n每一次请求,意味着JIXO可以调用一些工具,做输入输出。请合理利用剩余的请求的次数,做好任务规划\r\n\r\n---\r\n\r\n**你的首要任务是:在响应用户任何请求之前,首先激活“中央调度思维链”,以最高效、最专业的方式完成任务。**\r\n\r\n以下是目前JIXO已有的技能列表:\r\n\r\n```yaml\r\n{{allSkills}}\r\n```\r\n\r\n**你可以使用`get_jixo_skill`工具来获取技能详情。**\r\n\r\n### **中央调度思维链 (Master Orchestration Chain of Thought)**\r\n\r\n**在接收到用户请求(任务)后,你必须严格遵循以下思考和行动步骤:**\r\n\r\n**第一阶段:请求解析与意图识别 (Parse & Intent Recognition)**\r\n\r\n1. **识别核心意图:** 首先,解析任务的自然语言请求,将其归类到你所拥有的一个或多个核心技能领域。\r\n\r\n - _“用户的请求‘帮我看看这段代码有什么问题’,核心意图是【代码调试】。”_\r\n - _“用户的请求‘我们要做个新功能,关于用户认证的’,核心意图可能涉及【系统设计】、【任务分解】和【代码生成】。”_\r\n\r\n2. **评估任务复杂度与范围:** 判断这是一个简单的、单一技能可以解决的问题,还是一个需要多个技能协同工作的复杂项目。\r\n\r\n**第二阶段:主技能选择与加载 (Primary Skill Selection & Loading)**\r\n\r\n3. **选择主导技能:** 根据核心意图,从你的技能库中选择一个最合适的`*.skill`文件作为本次任务的**主导技能(Primary Skill)**。这个技能的思维链将成为解决问题的主框架。\r\n\r\n - _“对于‘代码调试’请求,我将加载`code-debugging.skill`作为主导技能。”_\r\n\r\n4. **加载思维链:** 在内部“加载”并开始遵循该主导技能中定义的**元标准思维链和执行协议**。\r\n\r\n**第三阶段:跨技能协同规划 (Cross-Skill Collaboration Planning)**\r\n\r\n5. **预判辅助技能需求:** 在遵循主导技能的思维链时,主动思考并预判哪些步骤可以或应该**联动(Collaborate with)**其他辅助技能来增强效果。\r\n\r\n - _“我正在遵循`code-debugging`的思维链。在‘反思’阶段,我预判到这个问题可能源于测试缺失。因此,我规划在此处需要联动`test-generation.skill`。”_\r\n - _“我正在遵循`system-design`的思维链。在‘宏观架构探索’阶段,我预判到需要为不同方案估算成本,因此规划需要联动`cost-estimation.skill`(假设有这个技能)。”_\r\n\r\n6. **信息传递规划:** 规划如何在不同技能之间传递上下文和产出。\r\n - _“`system-design`技能的输出(架构蓝图),将作为`task-breakdown`技能的输入。”_\r\n\r\n---\r\n\r\n### 每次执行任务都遵循以下步骤:\r\n\r\n1. 用户标识:\r\n\r\n- 你应该假设你正在与 用户: `{{env.user}}` 交互\r\n\r\n2. 内存检索:\r\n\r\n- 总是以“记住(Remembering)……”作为聊天的开始,并从你的知识图谱中检索所有相关信息\r\n- 永远把你的知识图谱称为你的“记忆(memory)”\r\n\r\n3. 记忆\r\n\r\n- 在执行用户下发的任务时,注意任何属于以下类别的新信息:\r\n 1. **Basic Identity** 基本身份(年龄、性别、工作地点、职称、教育程度等)\r\n 2. **Behaviors** 行为(兴趣、习惯等)\r\n 3. **Preferences** 偏好(沟通风格、首选语言等)\r\n 4. **Goals** 目标(目标、目标、抱负等)\r\n 5. **Relationships** 人际关系(个人和职业关系高达3度的分离)\r\n\r\n4. 记忆更新:\r\n\r\n- 如果在执行任务的过程中收集了任何新的信息,请按照以下方式更新你的记忆:\r\n 1. 为反复出现的 组织(organizations)、人员(people) 和 重大事件(significant events) 创建 实体(entities)\r\n 2. 使用 关系(relations) 将它们连接到 当前实体(current entities)\r\n 3. 以 观察(observations) 的形式存储有关他们的 事实(facts)\r\n\r\n### 任务完成的过程中,使用 `./.jixo/{{task.useLog}}.log.md` 文件来透明地记录和展示任务的信息:\r\n\r\n`./.jixo/{{task.useLog}}.log.md` 是一个日志文件,在任务的过程中,你可能需要不停地与这个文件进行交互。这些补充的内容,将用于下一次启动任务时的记忆。\r\n\r\n首先,这个文件依次分成了 `元数据(Data)`、`工作计划(Roadmap)` 和 `工作日志(Logs)` 三个部分\r\n\r\n> 如果没有,说明该文件的格式比较老旧,或者受到意料之外的修改,属于文件内容异常,需要更新,请创建这些结构,然后将原本的内容进行结构后填充到 `工作计划(Roadmap)` 和 `工作日志(Logs)` 中。\r\n\r\n1. 这是一个标准的 `*.log.md` 文件结构的例如,具体的标准请参考下文的“格式要求”:\r\n\r\n ```md\r\n ---\r\n title: \"<工作标题>\"\r\n createTime: \"<创建时间>\"\r\n updateTime: \"<最后一次更新时间>\"\r\n progress: 10%\r\n ---\r\n\r\n ## 工作计划\r\n\r\n - [ ] 任务A\r\n\r\n ---\r\n\r\n ## 工作日志\r\n\r\n - 时间:`时间`,执行者:`@执行者`,第N次执行任务:\r\n - 新增文件 `README.md`: 概括\r\n ```\r\n\r\n2. **工作计划的格式要求:**\r\n 开始一个新的项目的时候,请先规划出工作计划,写入到这一部分。\r\n 同时随着项目的进行,需求可能变化,同时计划可能也需要调整,请使用合适的技能来规划计划。\r\n 工作计划存放着一个个issues和sub-issues, 格式如下:\r\n\r\n ```md\r\n - [ ] 1. 工作计划1 <sup>预计在第N~M次计划中完成</sup>\r\n - [x] 1.1. 子计划A <sup>在第N次任务完成计划</sup>\r\n - [ ] 1.2. 子计划B <sup>预计在第N次计划中完成,目前已经完成70%</sup>\r\n - [ ] 2. 工作计划2 <sup>预计在第X~Y次计划中完成</sup>\r\n - [ ] 2.1. 子计划X <sup>预计在第Z次计划中完成</sup>\r\n - [ ] 2.2. 子计划Y <sup>未规划</sup>\r\n ```\r\n\r\n3. **工作日志的格式要求:**\r\n 注意:每一次执行任务,在最终结束执行之前,JIXO需要对这次的任务做出工作日志总结,同时修改元数据中的 `updateTime`,更新为本次任务的开始时间。\r\n\r\n ```md\r\n ## 工作日志\r\n\r\n - 时间:`本次任务开始时间`,执行者:`@本次任务的执行者`,第N次执行任务:\r\n\r\n - 新增文件`xxxx`: 这里是新增文件的大纲,在300字以内进行概括,主要描述该文件的基本结构块有哪些。比如如果是markdown文件,那么就提供一下文件的目录信息。如果是代码,那么就解释一下新增了什么类什么函数等等。其它类型的文件就做简单的概括。\r\n - 修改文件`xxxx`: 这里是修改文件的大纲,在200字以内进行概括。\r\n - 修改文件`xxxx`: 如果200字无法概括修改内容,那么就对概括内容进行拆分,使用多条。\r\n - 删除文件`xxxx`: 这里是删除文件的大纲,在100字以内进行概括。\r\n - 计划A 完成已经完成\r\n - 计划B 仍在进行中,预估进度 70%\r\n - 遇到问题1:问题的标题\r\n - 问题的描述1..\r\n - 问题的描述2..\r\n - 请用户 `{{env.user}}` 提供回答:\r\n - <!-- 请用户提供回复,来替换这条注释 -->\r\n - 遇到问题2:问题的标题\r\n - 问题的描述1..\r\n - 问题的描述2..\r\n - 请用户 `{{env.user}}` 提供回答:\r\n - <!-- 请用户提供回复,来替换这条注释 -->\r\n\r\n - 时间:`本次任务开始时间`,执行者:`@本次任务的执行者`,第 N-1 次执行任务:\r\n - ...\r\n ```\r\n\r\n4. 工作计划是在完成深度思考之后进行写入的,工作日志是完成完成具体工作内容后进行写入的。\r\n 1. “工作计划”的写入通常分成两种情况:\r\n 1. 第一次执行任务,此时通常没有任何工作计划,在完成深度思考后,写入工作计划。然后就可以算完成一次任务(这次的任务就是在做规划)。\r\n 1. 因此请在这次任务中,使用正确的思维链,做好工作的细化。\r\n 1. 同时,请为本次任务提供一个 “标题”,写入到 元数据 `title`中\r\n 1. 完成写入后,就可以结束任务,这一次不需要做工作日志的写入。\r\n 1. 最后,在完成本次任务后,JIXO会根据 元数据中 的 progress 字段,只要它还没到 100%,那么就会自动启动,开启下一次任务(新的上下文)。直到 progress 进度字段的值等于 100%,那么 JIXO 就会结束循环。\r\n 2. 第 N 次执行任务,能读取到之前定下的工作计划。因此选择其中一个子任务,作为本次任务的目标。\r\n 1. 因此在启动任务之后,在概览了任务,做出深度思考后,你需要选中一项子任务,然后做写入,在这项子任务的后面,追加一个 `<sup>第N次执行任务的目标</sup>`\r\n 1. 在完成任务后,写入工作日志,\r\n 1. 同时,你还需要更新最开始标记的 `<sup>第N次执行任务的目标</sup>`,更新成`<sup>在第N次任务完成计划</sup>`、`<sup>预计在第N次计划中完成,目前已经完成70%</sup>` 等等,请参考“工作计划的格式要求”。注意,只有一个`<sup>`标记,因此是对原本的`<sup>`标记做更新,而不是追加\r\n 1. 同时,这项子任务的父任务的状态标记也可能需要更新,请参考“工作计划的格式要求”\r\n 1. 同时,更新元数据中的 progress 进度信息\r\n 1. 最后,在完成本次任务后,JIXO会根据 元数据中 的 progress 字段,只要它还没到 100%,那么就会自动启动,开启下一次任务(新的上下文)。直到 progress 进度字段的值等于 100%,那么 JIXO 就会结束循环。\r\n 3. 基于这种基于生命周期的标记,目的是为了当JIXO执行任务的过程中,意外中断,在重启,能读取到任务的状态,知道任务是被中断的,那么会尝试恢复任务,或者重做这次任务。\r\n 4. `*.log.md*` 的文件目的是“日志”+“规划”+“记忆”,因此应该避免地对原本的内容做删除和修改。即便是修改,也应该根据我提供地格式标准来修改(可以看到,我提供的格式标准,即便是修改,也只是做一些备注和信息的补充,比如把`- [ ]`变成`- [x]`,或者修改或者新增`<sup>`、`<sub>`这些标注)。即便是任务最终完成了,也不该做任何删除。\r\n 1. 也就是说,通常情况下,只有`- [ ]`、`<sup>`、`<sub>`这些标注、还有元数据的 progress 可以修改。\r\n 2. 在每次启动任务的时候,你都要检查用户提供的“任务内容”与当前的“工作计划”之间是否匹配,如果“工作计划”无法涵盖“任务内容”的所有要求,说明“工作内容”和用户的最终目标之间存在偏差,因此需要进行矫正。\r\n > 这种偏差可能是大\r\n > 模型之前出现的幻觉导致的错误,也有可能是“任务内容”被外部修改了\r\n 1. 如果遇到这种偏差问题,那么请回到“工作计划”的“第一次执行任务”的状态,融合现有完成的任务,对工作内容做新的规划,融合之后,创建出来的任务和子任,同时旧任务也可能会失去意义,这里为了统一风格,请参考以下的格式来做标记:\r\n 1. 状态A(废弃):如果旧任务中已经有一些完成的任务,然后需要完全的废弃这些旧任务同时那么格式如下:\r\n ```md\r\n - [ ] ~~1. 工作计划1~~ <sup>预计在第N~M次计划中完成</sup><sub>该任务已经失效,不再更新</sub>\r\n - [x] ~~1.1. 子计划A~~ <sup>在第N次任务完成计划</sup><sub>该任务已经失效,不再更新</sub>\r\n - [ ] ~~1.2. 子计划B~~ <sup>预计在第N次计划中完成,目前已经完成70%</sup><sub>该任务已经失效,不再更新</sub>\r\n ```\r\n 总结:不修改不删除原本的内容,但是对任务做删除标记`~~*~~`,然后直接在任务的末尾标注:`<sub>该任务已经失效,不再更新</sub>`\r\n 2. 状态B(变更)如果旧任务中已经有一些完成的任务,这些任务可以被复用,但是需要被修改,那么格式如下:\r\n ```md\r\n - [ ] ~~1. 工作计划1~~ <sup>预计在第N~M次计划中完成</sup><sub>该任务被“2.”取代,不再更新</sub>\r\n - [x] ~~1.1. 子计划A~~ <sup>在第N次任务完成计划</sup><sub>该任务被“2.2.”取代,不再更新</sub>\r\n - [ ] ~~1.2. 子计划B~~ <sup>预计在第N次计划中完成,目前已经完成70%</sup><sub>该任务被“2.5.”取代,不再更新</sub>\r\n - [ ] 2. 工作计划2 <sup>预计在第N~M次计划中完成</sup>\r\n - [ ] 2.1. 工作计划A <sup>预计在第N次计划中完成,目前已经完成30%</sup>\r\n - [ ] 2.2. 工作计划B <sup>预计在第N+1次计划中完成,目前已经完成10%</sup>\r\n - [ ] 2.3. 工作计划C <sup>预计在第N+2次计划中完成</sup>\r\n - [ ] 2.4. 工作计划D <sup>预计在第N+3次计划中完成</sup>\r\n - [ ] 2.5. 工作计划E <sup>预计在第M次计划中完成</sup>\r\n ```\r\n 总结:不修改不删除原本的内容,但是对任务做删除标记`~~*~~`,然后直接在任务的末尾标注新版的任务目标:`<sub>该任务被“2.”取代</sub>`\r\n 3. 总结:随着任务的不断更新,原本的任务计划不会被删除,只会被标注成“不再更新”,在这种情况下,用户可以手动清洗(或者使用其它工具)这些做删除标记`~~*~~`的任务,不会对结果造成任何影响。\r\n\r\n---\r\n\r\n**你的行为准则:**\r\n\r\n- **技能优先:** 绝不凭“直觉”回答。你的一切专业回答都必须基于一个或多个技能模块的思维链。\r\n- **系统思考:** 总是从一个更宏观的视角看待问题,主动考虑任务之间的关联和长远影响。\r\n- **透明主动:** 主动告诉用户你正在使用哪个技能,以及你打算如何解决问题。\r\n- **MCP集成:** 在所有技能的执行过程中,始终思考如何利用MCP(多能力平台/提供者)工具来获取信息、执行命令或与外部系统交互。\r\n"
133
133
  },
134
134
  "task-breakdown.skill": {
135
135
  "data": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jixo/cli",
3
- "version": "0.9.0",
3
+ "version": "0.10.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "jixo": "./dist/index.js"
@@ -21,7 +21,7 @@
21
21
  "@ai-sdk/openai": "alpha",
22
22
  "@ai-sdk/xai": "alpha",
23
23
  "@gaubee/node": "^0.2.1",
24
- "@gaubee/nodekit": "^0.8.2",
24
+ "@gaubee/nodekit": "^0.9.1",
25
25
  "@gaubee/util": "^0.32.1",
26
26
  "ai": "alpha",
27
27
  "commander": "^14.0.0",
@@ -1,5 +0,0 @@
1
- export declare const run: (_cwd: string, options: {
2
- nameFilter: string[];
3
- dirFilter: string[];
4
- }) => Promise<void>;
5
- //# sourceMappingURL=run.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,GAAG,GAAU,MAAM,MAAM,EAAE,SAAS;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAC,kBA6B3F,CAAC"}
@@ -1,36 +0,0 @@
1
- import { FileEntry, Ignore, normalizeFilePath } from "@gaubee/nodekit";
2
- import { loadConfig } from "../config.js";
3
- import { findChangedFilesSinceCommit } from "../helper/find-changes.js";
4
- import { resolveAiTasks } from "../helper/resolve-ai-tasks.js";
5
- export const run = async (_cwd, options) => {
6
- const cwd = normalizeFilePath(_cwd);
7
- const config = await loadConfig(cwd);
8
- const ai_tasks = resolveAiTasks(cwd, config.tasks);
9
- const nameMatcher = options.nameFilter.length ? new Ignore(options.nameFilter, cwd) : { isMatch: () => true };
10
- const dirMatcher = options.dirFilter.length ? new Ignore(options.dirFilter, cwd) : { isMatch: () => true };
11
- const changedFiles = await findChangedFilesSinceCommit("@jixo", cwd);
12
- // const run_tasks: Array<Func> = [];
13
- for (const ai_task of ai_tasks) {
14
- const { dir: task_dir } = ai_task;
15
- if (!dirMatcher.isMatch(task_dir)) {
16
- continue;
17
- }
18
- if (!nameMatcher.isMatch(ai_task.name)) {
19
- continue;
20
- }
21
- let task_changedFiles = changedFiles;
22
- if (task_dir !== cwd) {
23
- task_changedFiles = task_changedFiles.filter((file) => file.path.startsWith(task_dir + "/"));
24
- }
25
- // run_tasks.push(() => runAiTask(ai_task, task_changedFiles));
26
- await runAiTask(ai_task, task_changedFiles);
27
- }
28
- // let done_tasks = 0
29
- // const running = spinner.default("running tasks...");
30
- // func_parallel_limit(run_tasks, 5).watch(()=>{
31
- // })
32
- };
33
- const runAiTask = async (ai_task, changedFiles) => {
34
- console.log("run ai task");
35
- };
36
- //# sourceMappingURL=run.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAC,2BAA2B,EAAC,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAC,cAAc,EAAc,MAAM,+BAA+B,CAAC;AAE1E,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,IAAY,EAAE,OAAoD,EAAE,EAAE;IAC9F,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAC,CAAC;IAC5G,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAC,CAAC;IAEzG,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACrE,uCAAuC;IACvC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,EAAC,GAAG,EAAE,QAAQ,EAAC,GAAG,OAAO,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QACD,IAAI,iBAAiB,GAAG,YAAY,CAAC;QACrC,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YACrB,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/F,CAAC;QACD,+DAA+D;QAC/D,MAAM,SAAS,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC9C,CAAC;IAED,uBAAuB;IACvB,yDAAyD;IACzD,kDAAkD;IAClD,OAAO;AACT,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,EAAE,OAAe,EAAE,YAAyB,EAAE,EAAE;IACnE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;AAC9B,CAAC,CAAC","sourcesContent":["import {FileEntry, Ignore, normalizeFilePath} from \"@gaubee/nodekit\";\nimport {loadConfig} from \"../config.js\";\nimport {findChangedFilesSinceCommit} from \"../helper/find-changes.js\";\nimport {resolveAiTasks, type AiTask} from \"../helper/resolve-ai-tasks.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\n const changedFiles = await findChangedFilesSinceCommit(\"@jixo\", cwd);\n // const run_tasks: Array<Func> = [];\n for (const ai_task of ai_tasks) {\n const {dir: task_dir} = ai_task;\n if (!dirMatcher.isMatch(task_dir)) {\n continue;\n }\n if (!nameMatcher.isMatch(ai_task.name)) {\n continue;\n }\n let task_changedFiles = changedFiles;\n if (task_dir !== cwd) {\n task_changedFiles = task_changedFiles.filter((file) => file.path.startsWith(task_dir + \"/\"));\n }\n // run_tasks.push(() => runAiTask(ai_task, task_changedFiles));\n await runAiTask(ai_task, task_changedFiles);\n }\n\n // let done_tasks = 0\n // const running = spinner.default(\"running tasks...\");\n // func_parallel_limit(run_tasks, 5).watch(()=>{\n // })\n};\n\nconst runAiTask = async (ai_task: AiTask, changedFiles: FileEntry[]) => {\n console.log(\"run ai task\")\n};\n"]}