@icebreakers/monorepo 3.0.3 → 3.1.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.
package/README.md CHANGED
@@ -11,6 +11,31 @@ pnpm add -D @icebreakers/monorepo@latest
11
11
  npx monorepo up
12
12
  # 帮助文档
13
13
  npx monorepo -h
14
+ # 生成 Agentic 任务模板
15
+ npx monorepo ai create -o agentic-task.md -f
16
+ # 或使用别名
17
+ npx monorepo ai new --name checkout
18
+ ```
19
+
20
+ `monorepo ai create`(别名 `ai new`)默认会把模板写入 `agentic/prompts/<timestamp>/prompt.md`,每次都会建一个以时间命名的目录,并在命令行提示可修改该目录名称,方便追加截图等素材;也可以通过参数自定义路径。
21
+
22
+ `monorepo ai create` 支持批量生成:
23
+
24
+ ```bash
25
+ # 基于名称自动落盘到 agentic/prompts/checkout.md(默认目录可在 monorepo.config.ts 中设置)
26
+ npx monorepo ai create --name checkout
27
+
28
+ # 使用任务清单一次生成多个文件(tasks.json 为字符串或对象数组)
29
+ npx monorepo ai create --tasks agentic/tasks.json --format md -f
30
+ ```
31
+
32
+ `agentic/tasks.json` 示例:
33
+
34
+ ```json
35
+ [
36
+ "checkout",
37
+ { "name": "payments", "format": "json", "force": true }
38
+ ]
14
39
  ```
15
40
 
16
41
  ### 配置文件
@@ -23,6 +48,12 @@ import { defineMonorepoConfig } from '@icebreakers/monorepo'
23
48
 
24
49
  export default defineMonorepoConfig({
25
50
  commands: {
51
+ ai: {
52
+ baseDir: 'agentic/custom-prompts',
53
+ format: 'json',
54
+ force: true,
55
+ tasksFile: 'agentic/tasks.json',
56
+ },
26
57
  create: {
27
58
  defaultTemplate: 'cli',
28
59
  renameJson: true,
@@ -39,7 +70,7 @@ export default defineMonorepoConfig({
39
70
  })
40
71
  ```
41
72
 
42
- 目前支持 `create`、`clean`、`sync`、`upgrade`、`init` 与 `mirror` 六类命令的默认参数覆写。
73
+ 目前支持 `ai`、`create`、`clean`、`sync`、`upgrade`、`init` 与 `mirror` 七类命令的默认参数覆写。
43
74
 
44
75
  ## 文档地址
45
76
 
@@ -42,39 +42,39 @@
42
42
  "devDependencies": {
43
43
  "@changesets/changelog-github": "^0.5.2",
44
44
  "@changesets/cli": "^2.29.8",
45
- "@commitlint/cli": "^20.1.0",
46
- "@icebreakers/commitlint-config": "^1.2.2",
47
- "@icebreakers/eslint-config": "^1.6.0",
45
+ "@commitlint/cli": "^20.2.0",
46
+ "@icebreakers/commitlint-config": "^1.2.3",
47
+ "@icebreakers/eslint-config": "^1.6.3",
48
48
  "@icebreakers/monorepo": "workspace:*",
49
49
  "@icebreakers/stylelint-config": "^1.2.3",
50
50
  "@types/fs-extra": "^11.0.4",
51
51
  "@types/node": "^24.10.1",
52
52
  "@types/semver": "^7.7.1",
53
- "@vitest/coverage-v8": "~4.0.14",
53
+ "@vitest/coverage-v8": "~4.0.15",
54
54
  "ci-info": "^4.3.1",
55
55
  "cross-env": "^10.1.0",
56
56
  "defu": "^6.1.4",
57
57
  "es-toolkit": "^1.42.0",
58
58
  "eslint": "^9.39.1",
59
- "execa": "^9.6.0",
59
+ "execa": "^9.6.1",
60
60
  "fs-extra": "^11.3.2",
61
61
  "husky": "^9.1.7",
62
62
  "lint-staged": "^16.2.7",
63
- "only-allow": "^1.2.1",
63
+ "only-allow": "^1.2.2",
64
64
  "pathe": "^2.0.3",
65
65
  "pkg-types": "^2.3.0",
66
66
  "rimraf": "^6.1.2",
67
67
  "stylelint": "^16.26.1",
68
- "tsdown": "^0.16.8",
68
+ "tsdown": "0.17.0",
69
69
  "tslib": "^2.8.1",
70
70
  "tsup": "^8.5.1",
71
- "tsx": "^4.20.6",
72
- "turbo": "^2.6.1",
73
- "type-fest": "^5.2.0",
71
+ "tsx": "^4.21.0",
72
+ "turbo": "^2.6.3",
73
+ "type-fest": "^5.3.0",
74
74
  "typescript": "^5.9.3",
75
75
  "unbuild": "^3.6.1",
76
- "vitest": "~4.0.14",
77
- "yaml": "^2.8.1"
76
+ "vitest": "~4.0.15",
77
+ "yaml": "^2.8.2"
78
78
  },
79
79
  "publishConfig": {
80
80
  "access": "public",
@@ -82,7 +82,7 @@ function resolveProjects(): string[] {
82
82
 
83
83
  const rootConfig = findConfig(rootPath)
84
84
  if (rootConfig) {
85
- projects.push(path.relative(ROOT_DIR, rootConfig))
85
+ projects.push(rootConfig)
86
86
  }
87
87
 
88
88
  const entries = fs.readdirSync(rootPath, { withFileTypes: true })
@@ -94,7 +94,7 @@ function resolveProjects(): string[] {
94
94
  const projectDir = path.join(rootPath, entry.name)
95
95
  const configPath = findConfig(projectDir)
96
96
  if (configPath) {
97
- projects.push(path.relative(ROOT_DIR, configPath))
97
+ projects.push(configPath)
98
98
  }
99
99
  }
100
100
  }
package/dist/cli.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_upgrade = require('./upgrade-BTMNNTgu.cjs');
1
+ const require_upgrade = require('./upgrade-D3k24_vK.cjs');
2
2
  let node_process = require("node:process");
3
3
  node_process = require_upgrade.__toESM(node_process);
4
4
  let __inquirer_input = require("@inquirer/input");
@@ -29,14 +29,53 @@ commander.program.command("sync").description("向 npmmirror 同步所有子包"
29
29
  await require_upgrade.syncNpmMirror(cwd);
30
30
  require_upgrade.logger.success("sync npm mirror finished!");
31
31
  });
32
- commander.program.command("clean").description("清除选中的包").action(async () => {
33
- await require_upgrade.cleanProjects(cwd);
32
+ commander.program.command("clean").description("清除选中的包").option("-y, --yes", "跳过交互直接清理(等价 autoConfirm)").option("--include-private", "包含 private 包").option("--pinned-version <version>", "覆盖写入的 @icebreakers/monorepo 版本").action(async (opts) => {
33
+ const overrides = {};
34
+ if (opts.yes) overrides.autoConfirm = true;
35
+ if (opts.includePrivate) overrides.includePrivate = true;
36
+ if (opts.pinnedVersion) overrides.pinnedVersion = opts.pinnedVersion;
37
+ await require_upgrade.cleanProjects(cwd, overrides);
34
38
  require_upgrade.logger.success("clean projects finished!");
35
39
  });
36
40
  commander.program.command("mirror").description("设置 VscodeBinaryMirror").action(async () => {
37
41
  await require_upgrade.setVscodeBinaryMirror(cwd);
38
42
  require_upgrade.logger.success("set vscode binary mirror finished!");
39
43
  });
44
+ commander.program.command("ai").description("AI 助手工具集").command("create").alias("new").description("生成 Agentic 任务提示词模板").option("-o, --output <path>", "输出到指定文件").option("-f, --force", "允许覆盖已存在文件").option("--format <md|json>", "模板格式,默认 md").option("-d, --dir <path>", "默认输出目录(默认 agentic/prompts,下级自动创建时间文件夹),配合 --name / --tasks 使用").option("-n, --name <name>", "使用名称快速生成文件,自动添加后缀").option("-t, --tasks <file>", "从 JSON 数组批量生成模板").action(async (opts) => {
45
+ const aiConfig = await require_upgrade.resolveCommandConfig("ai", cwd);
46
+ const format = opts.format ?? aiConfig?.format ?? "md";
47
+ const force = opts.force ?? aiConfig?.force ?? false;
48
+ const output = opts.output ?? aiConfig?.output;
49
+ const baseDir = opts.dir ?? aiConfig?.baseDir ?? require_upgrade.defaultAgenticBaseDir;
50
+ const tasksFile = opts.tasks ?? aiConfig?.tasksFile;
51
+ const name$1 = opts.name;
52
+ if (Boolean(tasksFile && !opts.output && !opts.name)) {
53
+ await require_upgrade.generateAgenticTemplates(await require_upgrade.loadAgenticTasks(tasksFile, cwd), {
54
+ cwd,
55
+ baseDir,
56
+ force,
57
+ format
58
+ });
59
+ return;
60
+ }
61
+ let folderName;
62
+ if (!output && !name$1) {
63
+ const generated = require_upgrade.createTimestampFolderName();
64
+ folderName = ((await (0, __inquirer_input.default)({
65
+ message: "提示词将写入哪个文件夹?(可回车确认或自定义)",
66
+ default: generated
67
+ }))?.trim?.() ?? generated) || generated;
68
+ }
69
+ await require_upgrade.generateAgenticTemplate({
70
+ cwd,
71
+ output,
72
+ force,
73
+ format,
74
+ baseDir,
75
+ name: name$1,
76
+ folderName
77
+ });
78
+ });
40
79
  commander.program.command("new").description("创建一个新的子包").alias("create").argument("[name]").action(async (name$1) => {
41
80
  const createConfig = await require_upgrade.resolveCommandConfig("create", cwd);
42
81
  if (!name$1) name$1 = await (0, __inquirer_input.default)({
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { E as cleanProjects, T as version, c as getCreateChoices, i as init, k as resolveCommandConfig, n as syncNpmMirror, o as createNewProject, r as setVscodeBinaryMirror, s as defaultTemplate, t as upgradeMonorepo, w as name, y as logger } from "./upgrade-CxCmaiou.mjs";
1
+ import { A as defaultAgenticBaseDir, C as name, M as generateAgenticTemplates, N as loadAgenticTasks, O as resolveCommandConfig, P as logger, T as cleanProjects, c as getCreateChoices, i as init, j as generateAgenticTemplate, k as createTimestampFolderName, n as syncNpmMirror, o as createNewProject, r as setVscodeBinaryMirror, s as defaultTemplate, t as upgradeMonorepo, w as version } from "./upgrade-DcCr5GIw.mjs";
2
2
  import process from "node:process";
3
3
  import input from "@inquirer/input";
4
4
  import select from "@inquirer/select";
@@ -26,14 +26,53 @@ program.command("sync").description("向 npmmirror 同步所有子包").action(a
26
26
  await syncNpmMirror(cwd);
27
27
  logger.success("sync npm mirror finished!");
28
28
  });
29
- program.command("clean").description("清除选中的包").action(async () => {
30
- await cleanProjects(cwd);
29
+ program.command("clean").description("清除选中的包").option("-y, --yes", "跳过交互直接清理(等价 autoConfirm)").option("--include-private", "包含 private 包").option("--pinned-version <version>", "覆盖写入的 @icebreakers/monorepo 版本").action(async (opts) => {
30
+ const overrides = {};
31
+ if (opts.yes) overrides.autoConfirm = true;
32
+ if (opts.includePrivate) overrides.includePrivate = true;
33
+ if (opts.pinnedVersion) overrides.pinnedVersion = opts.pinnedVersion;
34
+ await cleanProjects(cwd, overrides);
31
35
  logger.success("clean projects finished!");
32
36
  });
33
37
  program.command("mirror").description("设置 VscodeBinaryMirror").action(async () => {
34
38
  await setVscodeBinaryMirror(cwd);
35
39
  logger.success("set vscode binary mirror finished!");
36
40
  });
41
+ program.command("ai").description("AI 助手工具集").command("create").alias("new").description("生成 Agentic 任务提示词模板").option("-o, --output <path>", "输出到指定文件").option("-f, --force", "允许覆盖已存在文件").option("--format <md|json>", "模板格式,默认 md").option("-d, --dir <path>", "默认输出目录(默认 agentic/prompts,下级自动创建时间文件夹),配合 --name / --tasks 使用").option("-n, --name <name>", "使用名称快速生成文件,自动添加后缀").option("-t, --tasks <file>", "从 JSON 数组批量生成模板").action(async (opts) => {
42
+ const aiConfig = await resolveCommandConfig("ai", cwd);
43
+ const format = opts.format ?? aiConfig?.format ?? "md";
44
+ const force = opts.force ?? aiConfig?.force ?? false;
45
+ const output = opts.output ?? aiConfig?.output;
46
+ const baseDir = opts.dir ?? aiConfig?.baseDir ?? defaultAgenticBaseDir;
47
+ const tasksFile = opts.tasks ?? aiConfig?.tasksFile;
48
+ const name$1 = opts.name;
49
+ if (Boolean(tasksFile && !opts.output && !opts.name)) {
50
+ await generateAgenticTemplates(await loadAgenticTasks(tasksFile, cwd), {
51
+ cwd,
52
+ baseDir,
53
+ force,
54
+ format
55
+ });
56
+ return;
57
+ }
58
+ let folderName;
59
+ if (!output && !name$1) {
60
+ const generated = createTimestampFolderName();
61
+ folderName = ((await input({
62
+ message: "提示词将写入哪个文件夹?(可回车确认或自定义)",
63
+ default: generated
64
+ }))?.trim?.() ?? generated) || generated;
65
+ }
66
+ await generateAgenticTemplate({
67
+ cwd,
68
+ output,
69
+ force,
70
+ format,
71
+ baseDir,
72
+ name: name$1,
73
+ folderName
74
+ });
75
+ });
37
76
  program.command("new").description("创建一个新的子包").alias("create").argument("[name]").action(async (name$1) => {
38
77
  const createConfig = await resolveCommandConfig("create", cwd);
39
78
  if (!name$1) name$1 = await input({
package/dist/index.cjs CHANGED
@@ -1,12 +1,16 @@
1
- const require_upgrade = require('./upgrade-BTMNNTgu.cjs');
1
+ const require_upgrade = require('./upgrade-D3k24_vK.cjs');
2
2
 
3
3
  exports.GitClient = require_upgrade.GitClient;
4
4
  exports.assetsDir = require_upgrade.assetsDir;
5
5
  exports.cleanProjects = require_upgrade.cleanProjects;
6
6
  exports.createContext = require_upgrade.createContext;
7
7
  exports.createNewProject = require_upgrade.createNewProject;
8
+ exports.createTimestampFolderName = require_upgrade.createTimestampFolderName;
9
+ exports.defaultAgenticBaseDir = require_upgrade.defaultAgenticBaseDir;
8
10
  exports.defineMonorepoConfig = require_upgrade.defineMonorepoConfig;
9
11
  exports.escapeStringRegexp = require_upgrade.escapeStringRegexp;
12
+ exports.generateAgenticTemplate = require_upgrade.generateAgenticTemplate;
13
+ exports.generateAgenticTemplates = require_upgrade.generateAgenticTemplates;
10
14
  exports.getCreateChoices = require_upgrade.getCreateChoices;
11
15
  exports.getFileHash = require_upgrade.getFileHash;
12
16
  exports.getTemplateMap = require_upgrade.getTemplateMap;
@@ -17,6 +21,7 @@ exports.isFileChanged = require_upgrade.isFileChanged;
17
21
  exports.isGitignoreFile = require_upgrade.isGitignoreFile;
18
22
  exports.isIgnorableFsError = require_upgrade.isIgnorableFsError;
19
23
  exports.isMatch = require_upgrade.isMatch;
24
+ exports.loadAgenticTasks = require_upgrade.loadAgenticTasks;
20
25
  exports.loadMonorepoConfig = require_upgrade.loadMonorepoConfig;
21
26
  exports.logger = require_upgrade.logger;
22
27
  Object.defineProperty(exports, 'name', {
package/dist/index.d.cts CHANGED
@@ -39,6 +39,40 @@ interface CliOpts {
39
39
  skipOverwrite?: boolean;
40
40
  }
41
41
  //#endregion
42
+ //#region src/commands/ai.d.ts
43
+ type AgenticTemplateFormat = 'md' | 'json';
44
+ interface GenerateAgenticTemplateOptions {
45
+ cwd?: string;
46
+ output?: string;
47
+ force?: boolean;
48
+ format?: AgenticTemplateFormat;
49
+ /**
50
+ * 任务名,用于快速生成带目录与后缀的文件。
51
+ */
52
+ name?: string;
53
+ /**
54
+ * 基础目录,配合 name 使用。
55
+ * @default 'agentic/prompts'
56
+ */
57
+ baseDir?: string;
58
+ /**
59
+ * 自动生成目录时使用的自定义文件夹名称。
60
+ * @default 自动生成的时间戳
61
+ */
62
+ folderName?: string;
63
+ }
64
+ type AgenticTemplateTask = string | (Omit<GenerateAgenticTemplateOptions, 'cwd'> & {
65
+ name?: string;
66
+ });
67
+ declare const defaultAgenticBaseDir = "agentic/prompts";
68
+ declare function createTimestampFolderName(date?: Date): string;
69
+ /**
70
+ * 生成 Agentic 任务提示词模板,默认写入 agentic/prompts/<timestamp>/prompt.md,可自定义输出路径。
71
+ */
72
+ declare function generateAgenticTemplate(options?: GenerateAgenticTemplateOptions): Promise<string>;
73
+ declare function loadAgenticTasks(filePath: string, cwd: string): Promise<AgenticTemplateTask[]>;
74
+ declare function generateAgenticTemplates(tasks: AgenticTemplateTask[], defaults?: GenerateAgenticTemplateOptions): Promise<string[]>;
75
+ //#endregion
42
76
  //#region src/commands/create.d.ts
43
77
  /**
44
78
  * 内置模板映射表,value 指向仓库中对应模板所在路径。
@@ -120,6 +154,33 @@ interface GetWorkspacePackagesOptions {
120
154
  }
121
155
  //#endregion
122
156
  //#region src/types/config.d.ts
157
+ interface AiCommandConfig {
158
+ /**
159
+ * 默认输出路径,不填则自动创建 `agentic/prompts/<timestamp>/prompt.md` 文件夹与模板。
160
+ * @default undefined
161
+ */
162
+ output?: string;
163
+ /**
164
+ * 默认存放目录,配合 name / tasks 批量生成时使用。
165
+ * @default 'agentic/prompts'
166
+ */
167
+ baseDir?: string;
168
+ /**
169
+ * 是否允许覆盖已存在文件。
170
+ * @default false
171
+ */
172
+ force?: boolean;
173
+ /**
174
+ * 模板格式。
175
+ * @default 'md'
176
+ */
177
+ format?: AgenticTemplateFormat;
178
+ /**
179
+ * 任务清单文件路径(JSON 数组),用于批量生成。
180
+ * @default undefined
181
+ */
182
+ tasksFile?: string;
183
+ }
123
184
  /**
124
185
  * `monorepo new` 命令的配置项,允许外部覆写模板目录、模板清单等。
125
186
  */
@@ -284,6 +345,7 @@ interface MonorepoConfig {
284
345
  * @default {}
285
346
  */
286
347
  commands?: {
348
+ ai?: AiCommandConfig;
287
349
  create?: CreateCommandConfig;
288
350
  clean?: CleanCommandConfig;
289
351
  sync?: SyncCommandConfig;
@@ -366,7 +428,7 @@ declare function getWorkspaceData(cwd: string, options?: GetWorkspacePackagesOpt
366
428
  /**
367
429
  * 交互式清理被选中的包目录,同时重写根 package.json 中的 @icebreakers/monorepo 版本。
368
430
  */
369
- declare function cleanProjects(cwd: string): Promise<void>;
431
+ declare function cleanProjects(cwd: string, overrides?: Partial<CleanCommandConfig>): Promise<void>;
370
432
  //#endregion
371
433
  //#region src/commands/init/index.d.ts
372
434
  /**
@@ -506,4 +568,4 @@ declare function escapeStringRegexp(str: string): string;
506
568
  */
507
569
  declare function isMatch(str: string, arr: RegExp[]): boolean;
508
570
  //#endregion
509
- export { type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, CreateNewProjectOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, defineMonorepoConfig, escapeStringRegexp, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
571
+ export { AgenticTemplateFormat, AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, CreateNewProjectOptions, GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
package/dist/index.d.mts CHANGED
@@ -39,6 +39,40 @@ interface CliOpts {
39
39
  skipOverwrite?: boolean;
40
40
  }
41
41
  //#endregion
42
+ //#region src/commands/ai.d.ts
43
+ type AgenticTemplateFormat = 'md' | 'json';
44
+ interface GenerateAgenticTemplateOptions {
45
+ cwd?: string;
46
+ output?: string;
47
+ force?: boolean;
48
+ format?: AgenticTemplateFormat;
49
+ /**
50
+ * 任务名,用于快速生成带目录与后缀的文件。
51
+ */
52
+ name?: string;
53
+ /**
54
+ * 基础目录,配合 name 使用。
55
+ * @default 'agentic/prompts'
56
+ */
57
+ baseDir?: string;
58
+ /**
59
+ * 自动生成目录时使用的自定义文件夹名称。
60
+ * @default 自动生成的时间戳
61
+ */
62
+ folderName?: string;
63
+ }
64
+ type AgenticTemplateTask = string | (Omit<GenerateAgenticTemplateOptions, 'cwd'> & {
65
+ name?: string;
66
+ });
67
+ declare const defaultAgenticBaseDir = "agentic/prompts";
68
+ declare function createTimestampFolderName(date?: Date): string;
69
+ /**
70
+ * 生成 Agentic 任务提示词模板,默认写入 agentic/prompts/<timestamp>/prompt.md,可自定义输出路径。
71
+ */
72
+ declare function generateAgenticTemplate(options?: GenerateAgenticTemplateOptions): Promise<string>;
73
+ declare function loadAgenticTasks(filePath: string, cwd: string): Promise<AgenticTemplateTask[]>;
74
+ declare function generateAgenticTemplates(tasks: AgenticTemplateTask[], defaults?: GenerateAgenticTemplateOptions): Promise<string[]>;
75
+ //#endregion
42
76
  //#region src/commands/create.d.ts
43
77
  /**
44
78
  * 内置模板映射表,value 指向仓库中对应模板所在路径。
@@ -120,6 +154,33 @@ interface GetWorkspacePackagesOptions {
120
154
  }
121
155
  //#endregion
122
156
  //#region src/types/config.d.ts
157
+ interface AiCommandConfig {
158
+ /**
159
+ * 默认输出路径,不填则自动创建 `agentic/prompts/<timestamp>/prompt.md` 文件夹与模板。
160
+ * @default undefined
161
+ */
162
+ output?: string;
163
+ /**
164
+ * 默认存放目录,配合 name / tasks 批量生成时使用。
165
+ * @default 'agentic/prompts'
166
+ */
167
+ baseDir?: string;
168
+ /**
169
+ * 是否允许覆盖已存在文件。
170
+ * @default false
171
+ */
172
+ force?: boolean;
173
+ /**
174
+ * 模板格式。
175
+ * @default 'md'
176
+ */
177
+ format?: AgenticTemplateFormat;
178
+ /**
179
+ * 任务清单文件路径(JSON 数组),用于批量生成。
180
+ * @default undefined
181
+ */
182
+ tasksFile?: string;
183
+ }
123
184
  /**
124
185
  * `monorepo new` 命令的配置项,允许外部覆写模板目录、模板清单等。
125
186
  */
@@ -284,6 +345,7 @@ interface MonorepoConfig {
284
345
  * @default {}
285
346
  */
286
347
  commands?: {
348
+ ai?: AiCommandConfig;
287
349
  create?: CreateCommandConfig;
288
350
  clean?: CleanCommandConfig;
289
351
  sync?: SyncCommandConfig;
@@ -366,7 +428,7 @@ declare function getWorkspaceData(cwd: string, options?: GetWorkspacePackagesOpt
366
428
  /**
367
429
  * 交互式清理被选中的包目录,同时重写根 package.json 中的 @icebreakers/monorepo 版本。
368
430
  */
369
- declare function cleanProjects(cwd: string): Promise<void>;
431
+ declare function cleanProjects(cwd: string, overrides?: Partial<CleanCommandConfig>): Promise<void>;
370
432
  //#endregion
371
433
  //#region src/commands/init/index.d.ts
372
434
  /**
@@ -506,4 +568,4 @@ declare function escapeStringRegexp(str: string): string;
506
568
  */
507
569
  declare function isMatch(str: string, arr: RegExp[]): boolean;
508
570
  //#endregion
509
- export { type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, type CreateNewProjectOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, defineMonorepoConfig, escapeStringRegexp, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
571
+ export { type AgenticTemplateFormat, type AgenticTemplateTask, type AiCommandConfig, type CleanCommandConfig, type CliOpts, type ConfigValues, Context, type CreateChoiceOption, type CreateCommandConfig, type CreateNewProjectOptions, type GenerateAgenticTemplateOptions, type GetWorkspacePackagesOptions, GitClient, type InitCommandConfig, type MirrorCommandConfig, type MonorepoConfig, type PackageJson, type SimpleGit, type SimpleGitOptions, type SyncCommandConfig, type UpgradeCommandConfig, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { A as getWorkspaceData, C as templatesDir, D as defineMonorepoConfig, E as cleanProjects, M as GitClient, O as loadMonorepoConfig, S as rootDir, T as version, _ as toWorkspaceGitignorePath, a as createContext, b as assetsDir, c as getCreateChoices, d as escapeStringRegexp, f as isMatch, g as toPublishGitignorePath, h as isGitignoreFile, i as init, j as getWorkspacePackages, k as resolveCommandConfig, l as getTemplateMap, m as isFileChanged, n as syncNpmMirror, o as createNewProject, p as getFileHash, r as setVscodeBinaryMirror, t as upgradeMonorepo, u as templateMap, v as isIgnorableFsError, w as name, x as packageDir, y as logger } from "./upgrade-CxCmaiou.mjs";
1
+ import { A as defaultAgenticBaseDir, C as name, D as loadMonorepoConfig, E as defineMonorepoConfig, F as getWorkspaceData, I as getWorkspacePackages, L as GitClient, M as generateAgenticTemplates, N as loadAgenticTasks, O as resolveCommandConfig, P as logger, S as templatesDir, T as cleanProjects, _ as toWorkspaceGitignorePath, a as createContext, b as packageDir, c as getCreateChoices, d as escapeStringRegexp, f as isMatch, g as toPublishGitignorePath, h as isGitignoreFile, i as init, j as generateAgenticTemplate, k as createTimestampFolderName, l as getTemplateMap, m as isFileChanged, n as syncNpmMirror, o as createNewProject, p as getFileHash, r as setVscodeBinaryMirror, t as upgradeMonorepo, u as templateMap, v as isIgnorableFsError, w as version, x as rootDir, y as assetsDir } from "./upgrade-DcCr5GIw.mjs";
2
2
 
3
- export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, defineMonorepoConfig, escapeStringRegexp, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
3
+ export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, syncNpmMirror, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, upgradeMonorepo, version };
@@ -34,19 +34,19 @@ let __pnpm_workspace_find_packages = require("@pnpm/workspace.find-packages");
34
34
  let __pnpm_workspace_read_manifest = require("@pnpm/workspace.read-manifest");
35
35
  let pathe = require("pathe");
36
36
  pathe = __toESM(pathe);
37
- let __inquirer_checkbox = require("@inquirer/checkbox");
38
- __inquirer_checkbox = __toESM(__inquirer_checkbox);
37
+ let node_process = require("node:process");
38
+ node_process = __toESM(node_process);
39
39
  let fs_extra = require("fs-extra");
40
40
  fs_extra = __toESM(fs_extra);
41
+ let consola = require("consola");
42
+ let __inquirer_checkbox = require("@inquirer/checkbox");
43
+ __inquirer_checkbox = __toESM(__inquirer_checkbox);
41
44
  let c12 = require("c12");
42
- let node_process = require("node:process");
43
- node_process = __toESM(node_process);
44
45
  let picocolors = require("picocolors");
45
46
  picocolors = __toESM(picocolors);
46
47
  let node_path = require("node:path");
47
48
  node_path = __toESM(node_path);
48
49
  let node_url = require("node:url");
49
- let consola = require("consola");
50
50
  let node_crypto = require("node:crypto");
51
51
  node_crypto = __toESM(node_crypto);
52
52
  require("@pnpm/types");
@@ -72,9 +72,9 @@ var join = /* @__PURE__ */ __name((segs, joinChar, options) => {
72
72
  if (typeof options.join === "function") return options.join(segs);
73
73
  return segs[0] + joinChar + segs[1];
74
74
  }, "join");
75
- var split$1 = /* @__PURE__ */ __name((path$12, splitChar, options) => {
76
- if (typeof options.split === "function") return options.split(path$12);
77
- return path$12.split(splitChar);
75
+ var split$1 = /* @__PURE__ */ __name((path$13, splitChar, options) => {
76
+ if (typeof options.split === "function") return options.split(path$13);
77
+ return path$13.split(splitChar);
78
78
  }, "split");
79
79
  var isValid = /* @__PURE__ */ __name((key, target = {}, options) => {
80
80
  if (typeof options?.isValid === "function") return options.isValid(key, target);
@@ -83,17 +83,17 @@ var isValid = /* @__PURE__ */ __name((key, target = {}, options) => {
83
83
  var isValidObject = /* @__PURE__ */ __name((v) => {
84
84
  return isObject$2(v) || typeof v === "function";
85
85
  }, "isValidObject");
86
- var index_default = /* @__PURE__ */ __name((target, path$12, options = {}) => {
86
+ var index_default = /* @__PURE__ */ __name((target, path$13, options = {}) => {
87
87
  if (!isObject$2(options)) options = { default: options };
88
88
  if (!isValidObject(target)) return typeof options.default !== "undefined" ? options.default : target;
89
- if (typeof path$12 === "number") path$12 = String(path$12);
90
- const pathIsArray = Array.isArray(path$12);
91
- const pathIsString = typeof path$12 === "string";
89
+ if (typeof path$13 === "number") path$13 = String(path$13);
90
+ const pathIsArray = Array.isArray(path$13);
91
+ const pathIsString = typeof path$13 === "string";
92
92
  const splitChar = options.separator || ".";
93
93
  const joinChar = options.joinChar || (typeof splitChar === "string" ? splitChar : ".");
94
94
  if (!pathIsString && !pathIsArray) return target;
95
- if (target[path$12] !== void 0) return isValid(path$12, target, options) ? target[path$12] : options.default;
96
- const segs = pathIsArray ? path$12 : split$1(path$12, splitChar, options);
95
+ if (target[path$13] !== void 0) return isValid(path$13, target, options) ? target[path$13] : options.default;
96
+ const segs = pathIsArray ? path$13 : split$1(path$13, splitChar, options);
97
97
  const len = segs.length;
98
98
  let idx = 0;
99
99
  do {
@@ -275,6 +275,84 @@ async function getWorkspaceData(cwd, options) {
275
275
  };
276
276
  }
277
277
 
278
+ //#endregion
279
+ //#region src/core/logger.ts
280
+ /**
281
+ * 统一的日志实例,便于在命令行中输出带有前缀和颜色的消息。
282
+ */
283
+ const logger = (0, consola.createConsola)();
284
+
285
+ //#endregion
286
+ //#region src/commands/ai.ts
287
+ const agenticSections = [
288
+ "目标/产物",
289
+ "约束(性能/风格/兼容/不可改动范围)",
290
+ "验收标准(要跑的命令、预期输出/文件)",
291
+ "仓库路径",
292
+ "允许操作(可/不可写文件,可运行的命令清单,可否联网)",
293
+ "上下文线索(日志/文件/模块/相关 issue)",
294
+ "里程碑(根因→设计→实现→验证)"
295
+ ];
296
+ const defaultAgenticBaseDir = "agentic/prompts";
297
+ function renderMarkdownTemplate() {
298
+ return `${agenticSections.map((title) => `## ${title}\n- `).join("\n\n")}\n`;
299
+ }
300
+ function renderJsonTemplate() {
301
+ const payload = {};
302
+ for (const title of agenticSections) payload[title] = "";
303
+ return `${JSON.stringify(payload, null, 2)}\n`;
304
+ }
305
+ function createTimestampFolderName(date = /* @__PURE__ */ new Date()) {
306
+ const pad = (value) => value.toString().padStart(2, "0");
307
+ return `${date.getUTCFullYear()}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}-${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}${pad(date.getUTCSeconds())}`;
308
+ }
309
+ /**
310
+ * 生成 Agentic 任务提示词模板,默认写入 agentic/prompts/<timestamp>/prompt.md,可自定义输出路径。
311
+ */
312
+ async function generateAgenticTemplate(options = {}) {
313
+ const cwd = options.cwd ?? node_process.default.cwd();
314
+ const format = options.format ?? "md";
315
+ const baseDir = options.baseDir ?? defaultAgenticBaseDir;
316
+ if (format !== "md" && format !== "json") throw new Error(`不支持的模板格式:${format}`);
317
+ const template = format === "md" ? renderMarkdownTemplate() : renderJsonTemplate();
318
+ const ext = format === "json" ? "json" : "md";
319
+ let outputPath = options.output;
320
+ if (!outputPath && options.name) outputPath = pathe.default.join(baseDir, `${options.name}.${ext}`);
321
+ if (!outputPath) {
322
+ const folderName = options.folderName ?? createTimestampFolderName();
323
+ outputPath = pathe.default.join(baseDir, folderName, `prompt.${ext}`);
324
+ }
325
+ const targetPath = pathe.default.resolve(cwd, outputPath);
326
+ const targetDir = pathe.default.dirname(targetPath);
327
+ await fs_extra.default.ensureDir(targetDir);
328
+ const exists = await fs_extra.default.pathExists(targetPath);
329
+ if (exists && !options.force) throw new Error(`目标文件已存在:${pathe.default.relative(cwd, targetPath)}`);
330
+ await fs_extra.default.outputFile(targetPath, template, "utf8");
331
+ const actionLabel = exists ? "已覆盖模板" : "已生成模板";
332
+ logger.success(`${actionLabel}:${pathe.default.relative(cwd, targetPath)}`);
333
+ return template;
334
+ }
335
+ async function loadAgenticTasks(filePath, cwd) {
336
+ const fullPath = pathe.default.resolve(cwd, filePath);
337
+ const tasks = await fs_extra.default.readJson(fullPath);
338
+ if (!Array.isArray(tasks)) throw new TypeError("任务清单需要是数组");
339
+ return tasks;
340
+ }
341
+ async function generateAgenticTemplates(tasks, defaults = {}) {
342
+ const results = [];
343
+ for (const task of tasks) {
344
+ const normalized = typeof task === "string" ? {
345
+ ...defaults,
346
+ name: task
347
+ } : {
348
+ ...defaults,
349
+ ...task
350
+ };
351
+ results.push(await generateAgenticTemplate(normalized));
352
+ }
353
+ return results;
354
+ }
355
+
278
356
  //#endregion
279
357
  //#region ../../node_modules/.pnpm/is-primitive@3.0.1/node_modules/is-primitive/index.js
280
358
  /*!
@@ -414,9 +492,9 @@ var require_set_value = /* @__PURE__ */ __commonJSMin(((exports, module) => {
414
492
  } else obj[prop] = value;
415
493
  return obj;
416
494
  };
417
- const setValue = (target, path$12, value, options) => {
418
- if (!path$12 || !isObject(target)) return target;
419
- const keys = split(path$12, options);
495
+ const setValue = (target, path$13, value, options) => {
496
+ if (!path$13 || !isObject(target)) return target;
497
+ const keys = split(path$13, options);
420
498
  let obj = target;
421
499
  for (let i = 0; i < keys.length; i++) {
422
500
  const key = keys[i];
@@ -491,11 +569,19 @@ async function resolveCommandConfig(name$1, cwd) {
491
569
  //#endregion
492
570
  //#region src/commands/clean.ts
493
571
  var import_set_value$5 = /* @__PURE__ */ __toESM(require_set_value(), 1);
572
+ function mergeCleanConfig(base, overrides) {
573
+ if (!overrides) return base;
574
+ const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
575
+ return {
576
+ ...base,
577
+ ...definedOverrides
578
+ };
579
+ }
494
580
  /**
495
581
  * 交互式清理被选中的包目录,同时重写根 package.json 中的 @icebreakers/monorepo 版本。
496
582
  */
497
- async function cleanProjects(cwd) {
498
- const cleanConfig = await resolveCommandConfig("clean", cwd);
583
+ async function cleanProjects(cwd, overrides) {
584
+ const cleanConfig = mergeCleanConfig(await resolveCommandConfig("clean", cwd), overrides);
499
585
  const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ? { ignorePrivatePackage: false } : void 0);
500
586
  const filteredPackages = packages.filter((pkg) => {
501
587
  const name$2 = pkg.manifest.name ?? "";
@@ -529,7 +615,7 @@ async function cleanProjects(cwd) {
529
615
  //#endregion
530
616
  //#region package.json
531
617
  var name = "@icebreakers/monorepo";
532
- var version = "3.0.3";
618
+ var version = "3.1.1";
533
619
 
534
620
  //#endregion
535
621
  //#region src/constants.ts
@@ -554,13 +640,6 @@ const assetsDir = node_path.default.join(packageDir, "assets");
554
640
  */
555
641
  const rootDir = node_path.default.resolve(packageDir, "..", "..");
556
642
 
557
- //#endregion
558
- //#region src/core/logger.ts
559
- /**
560
- * 统一的日志实例,便于在命令行中输出带有前缀和颜色的消息。
561
- */
562
- const logger = (0, consola.createConsola)();
563
-
564
643
  //#endregion
565
644
  //#region src/utils/fs.ts
566
645
  /**
@@ -1357,6 +1436,18 @@ Object.defineProperty(exports, 'createNewProject', {
1357
1436
  return createNewProject;
1358
1437
  }
1359
1438
  });
1439
+ Object.defineProperty(exports, 'createTimestampFolderName', {
1440
+ enumerable: true,
1441
+ get: function () {
1442
+ return createTimestampFolderName;
1443
+ }
1444
+ });
1445
+ Object.defineProperty(exports, 'defaultAgenticBaseDir', {
1446
+ enumerable: true,
1447
+ get: function () {
1448
+ return defaultAgenticBaseDir;
1449
+ }
1450
+ });
1360
1451
  Object.defineProperty(exports, 'defaultTemplate', {
1361
1452
  enumerable: true,
1362
1453
  get: function () {
@@ -1375,6 +1466,18 @@ Object.defineProperty(exports, 'escapeStringRegexp', {
1375
1466
  return escapeStringRegexp;
1376
1467
  }
1377
1468
  });
1469
+ Object.defineProperty(exports, 'generateAgenticTemplate', {
1470
+ enumerable: true,
1471
+ get: function () {
1472
+ return generateAgenticTemplate;
1473
+ }
1474
+ });
1475
+ Object.defineProperty(exports, 'generateAgenticTemplates', {
1476
+ enumerable: true,
1477
+ get: function () {
1478
+ return generateAgenticTemplates;
1479
+ }
1480
+ });
1378
1481
  Object.defineProperty(exports, 'getCreateChoices', {
1379
1482
  enumerable: true,
1380
1483
  get: function () {
@@ -1435,6 +1538,12 @@ Object.defineProperty(exports, 'isMatch', {
1435
1538
  return isMatch;
1436
1539
  }
1437
1540
  });
1541
+ Object.defineProperty(exports, 'loadAgenticTasks', {
1542
+ enumerable: true,
1543
+ get: function () {
1544
+ return loadAgenticTasks;
1545
+ }
1546
+ });
1438
1547
  Object.defineProperty(exports, 'loadMonorepoConfig', {
1439
1548
  enumerable: true,
1440
1549
  get: function () {
@@ -4,14 +4,14 @@ import { findWorkspaceDir } from "@pnpm/find-workspace-dir";
4
4
  import { findWorkspacePackages } from "@pnpm/workspace.find-packages";
5
5
  import { readWorkspaceManifest } from "@pnpm/workspace.read-manifest";
6
6
  import path from "pathe";
7
- import checkbox from "@inquirer/checkbox";
7
+ import process from "node:process";
8
8
  import fs from "fs-extra";
9
+ import { createConsola } from "consola";
10
+ import checkbox from "@inquirer/checkbox";
9
11
  import { loadConfig } from "c12";
10
- import process from "node:process";
11
12
  import pc from "picocolors";
12
13
  import path$1 from "node:path";
13
14
  import { fileURLToPath } from "node:url";
14
- import { createConsola } from "consola";
15
15
  import crypto from "node:crypto";
16
16
  import "@pnpm/types";
17
17
  import { parse, stringify } from "comment-json";
@@ -264,6 +264,84 @@ async function getWorkspaceData(cwd, options) {
264
264
  };
265
265
  }
266
266
 
267
+ //#endregion
268
+ //#region src/core/logger.ts
269
+ /**
270
+ * 统一的日志实例,便于在命令行中输出带有前缀和颜色的消息。
271
+ */
272
+ const logger = createConsola();
273
+
274
+ //#endregion
275
+ //#region src/commands/ai.ts
276
+ const agenticSections = [
277
+ "目标/产物",
278
+ "约束(性能/风格/兼容/不可改动范围)",
279
+ "验收标准(要跑的命令、预期输出/文件)",
280
+ "仓库路径",
281
+ "允许操作(可/不可写文件,可运行的命令清单,可否联网)",
282
+ "上下文线索(日志/文件/模块/相关 issue)",
283
+ "里程碑(根因→设计→实现→验证)"
284
+ ];
285
+ const defaultAgenticBaseDir = "agentic/prompts";
286
+ function renderMarkdownTemplate() {
287
+ return `${agenticSections.map((title) => `## ${title}\n- `).join("\n\n")}\n`;
288
+ }
289
+ function renderJsonTemplate() {
290
+ const payload = {};
291
+ for (const title of agenticSections) payload[title] = "";
292
+ return `${JSON.stringify(payload, null, 2)}\n`;
293
+ }
294
+ function createTimestampFolderName(date = /* @__PURE__ */ new Date()) {
295
+ const pad = (value) => value.toString().padStart(2, "0");
296
+ return `${date.getUTCFullYear()}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}-${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}${pad(date.getUTCSeconds())}`;
297
+ }
298
+ /**
299
+ * 生成 Agentic 任务提示词模板,默认写入 agentic/prompts/<timestamp>/prompt.md,可自定义输出路径。
300
+ */
301
+ async function generateAgenticTemplate(options = {}) {
302
+ const cwd = options.cwd ?? process.cwd();
303
+ const format = options.format ?? "md";
304
+ const baseDir = options.baseDir ?? defaultAgenticBaseDir;
305
+ if (format !== "md" && format !== "json") throw new Error(`不支持的模板格式:${format}`);
306
+ const template = format === "md" ? renderMarkdownTemplate() : renderJsonTemplate();
307
+ const ext = format === "json" ? "json" : "md";
308
+ let outputPath = options.output;
309
+ if (!outputPath && options.name) outputPath = path.join(baseDir, `${options.name}.${ext}`);
310
+ if (!outputPath) {
311
+ const folderName = options.folderName ?? createTimestampFolderName();
312
+ outputPath = path.join(baseDir, folderName, `prompt.${ext}`);
313
+ }
314
+ const targetPath = path.resolve(cwd, outputPath);
315
+ const targetDir = path.dirname(targetPath);
316
+ await fs.ensureDir(targetDir);
317
+ const exists = await fs.pathExists(targetPath);
318
+ if (exists && !options.force) throw new Error(`目标文件已存在:${path.relative(cwd, targetPath)}`);
319
+ await fs.outputFile(targetPath, template, "utf8");
320
+ const actionLabel = exists ? "已覆盖模板" : "已生成模板";
321
+ logger.success(`${actionLabel}:${path.relative(cwd, targetPath)}`);
322
+ return template;
323
+ }
324
+ async function loadAgenticTasks(filePath, cwd) {
325
+ const fullPath = path.resolve(cwd, filePath);
326
+ const tasks = await fs.readJson(fullPath);
327
+ if (!Array.isArray(tasks)) throw new TypeError("任务清单需要是数组");
328
+ return tasks;
329
+ }
330
+ async function generateAgenticTemplates(tasks, defaults = {}) {
331
+ const results = [];
332
+ for (const task of tasks) {
333
+ const normalized = typeof task === "string" ? {
334
+ ...defaults,
335
+ name: task
336
+ } : {
337
+ ...defaults,
338
+ ...task
339
+ };
340
+ results.push(await generateAgenticTemplate(normalized));
341
+ }
342
+ return results;
343
+ }
344
+
267
345
  //#endregion
268
346
  //#region ../../node_modules/.pnpm/is-primitive@3.0.1/node_modules/is-primitive/index.js
269
347
  /*!
@@ -480,11 +558,19 @@ async function resolveCommandConfig(name$1, cwd) {
480
558
  //#endregion
481
559
  //#region src/commands/clean.ts
482
560
  var import_set_value$5 = /* @__PURE__ */ __toESM(require_set_value(), 1);
561
+ function mergeCleanConfig(base, overrides) {
562
+ if (!overrides) return base;
563
+ const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
564
+ return {
565
+ ...base,
566
+ ...definedOverrides
567
+ };
568
+ }
483
569
  /**
484
570
  * 交互式清理被选中的包目录,同时重写根 package.json 中的 @icebreakers/monorepo 版本。
485
571
  */
486
- async function cleanProjects(cwd) {
487
- const cleanConfig = await resolveCommandConfig("clean", cwd);
572
+ async function cleanProjects(cwd, overrides) {
573
+ const cleanConfig = mergeCleanConfig(await resolveCommandConfig("clean", cwd), overrides);
488
574
  const { packages, workspaceDir } = await getWorkspaceData(cwd, cleanConfig?.includePrivate ? { ignorePrivatePackage: false } : void 0);
489
575
  const filteredPackages = packages.filter((pkg) => {
490
576
  const name$2 = pkg.manifest.name ?? "";
@@ -518,7 +604,7 @@ async function cleanProjects(cwd) {
518
604
  //#endregion
519
605
  //#region package.json
520
606
  var name = "@icebreakers/monorepo";
521
- var version = "3.0.3";
607
+ var version = "3.1.1";
522
608
 
523
609
  //#endregion
524
610
  //#region src/constants.ts
@@ -543,13 +629,6 @@ const assetsDir = path$1.join(packageDir, "assets");
543
629
  */
544
630
  const rootDir = path$1.resolve(packageDir, "..", "..");
545
631
 
546
- //#endregion
547
- //#region src/core/logger.ts
548
- /**
549
- * 统一的日志实例,便于在命令行中输出带有前缀和颜色的消息。
550
- */
551
- const logger = createConsola();
552
-
553
632
  //#endregion
554
633
  //#region src/utils/fs.ts
555
634
  /**
@@ -1310,4 +1389,4 @@ async function upgradeMonorepo(opts) {
1310
1389
  }
1311
1390
 
1312
1391
  //#endregion
1313
- export { getWorkspaceData as A, templatesDir as C, defineMonorepoConfig as D, cleanProjects as E, GitClient as M, loadMonorepoConfig as O, rootDir as S, version as T, toWorkspaceGitignorePath as _, createContext as a, assetsDir as b, getCreateChoices as c, escapeStringRegexp as d, isMatch as f, toPublishGitignorePath as g, isGitignoreFile as h, init as i, getWorkspacePackages as j, resolveCommandConfig as k, getTemplateMap as l, isFileChanged as m, syncNpmMirror as n, createNewProject as o, getFileHash as p, setVscodeBinaryMirror as r, defaultTemplate as s, upgradeMonorepo as t, templateMap as u, isIgnorableFsError as v, name as w, packageDir as x, logger as y };
1392
+ export { defaultAgenticBaseDir as A, name as C, loadMonorepoConfig as D, defineMonorepoConfig as E, getWorkspaceData as F, getWorkspacePackages as I, GitClient as L, generateAgenticTemplates as M, loadAgenticTasks as N, resolveCommandConfig as O, logger as P, templatesDir as S, cleanProjects as T, toWorkspaceGitignorePath as _, createContext as a, packageDir as b, getCreateChoices as c, escapeStringRegexp as d, isMatch as f, toPublishGitignorePath as g, isGitignoreFile as h, init as i, generateAgenticTemplate as j, createTimestampFolderName as k, getTemplateMap as l, isFileChanged as m, syncNpmMirror as n, createNewProject as o, getFileHash as p, setVscodeBinaryMirror as r, defaultTemplate as s, upgradeMonorepo as t, templateMap as u, isIgnorableFsError as v, version as w, rootDir as x, assetsDir as y };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/monorepo",
3
3
  "type": "module",
4
- "version": "3.0.3",
4
+ "version": "3.1.1",
5
5
  "description": "The icebreaker's monorepo manager",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -58,20 +58,20 @@
58
58
  "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
59
59
  },
60
60
  "dependencies": {
61
- "@inquirer/checkbox": "^5.0.1",
62
- "@inquirer/input": "^5.0.1",
63
- "@inquirer/select": "^5.0.1",
61
+ "@inquirer/checkbox": "^5.0.2",
62
+ "@inquirer/input": "^5.0.2",
63
+ "@inquirer/select": "^5.0.2",
64
64
  "@pnpm/find-workspace-dir": "^1000.1.3",
65
65
  "@pnpm/logger": "^1001.0.1",
66
66
  "@pnpm/types": "^1001.0.1",
67
67
  "@pnpm/worker": "^1000.4.0",
68
- "@pnpm/workspace.find-packages": "^1000.0.47",
68
+ "@pnpm/workspace.find-packages": "^1000.0.48",
69
69
  "@pnpm/workspace.read-manifest": "^1000.2.7",
70
70
  "c12": "^3.3.2",
71
71
  "commander": "^14.0.2",
72
72
  "comment-json": "^4.4.1",
73
73
  "consola": "^3.4.2",
74
- "execa": "^9.6.0",
74
+ "execa": "^9.6.1",
75
75
  "fs-extra": "^11.3.2",
76
76
  "git-url-parse": "^16.1.0",
77
77
  "klaw": "^4.1.0",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@faker-js/faker": "^10.1.0",
18
- "@tanstack/vue-query": "^5.92.0",
18
+ "@tanstack/vue-query": "^5.92.1",
19
19
  "@tanstack/vue-query-devtools": "^6.1.2",
20
20
  "@tanstack/vue-table": "^8.21.3",
21
21
  "@tanstack/vue-virtual": "^3.13.12",
@@ -29,7 +29,7 @@
29
29
  "vue-router": "^4.6.3"
30
30
  },
31
31
  "devDependencies": {
32
- "@cloudflare/vite-plugin": "^1.15.3",
32
+ "@cloudflare/vite-plugin": "^1.17.0",
33
33
  "@hono/node-server": "^1.19.6",
34
34
  "@hono/trpc-server": "^0.4.0",
35
35
  "@tailwindcss/vite": "^4.1.17",
@@ -40,12 +40,12 @@
40
40
  "hono": "^4.10.7",
41
41
  "tailwindcss": "^4.1.17",
42
42
  "typescript": "~5.9.3",
43
- "unplugin-vue-router": "^0.18.0",
44
- "vite": "^7.2.4",
43
+ "unplugin-vue-router": "^0.19.0",
44
+ "vite": "^7.2.6",
45
45
  "vite-plugin-vue-devtools": "^8.0.5",
46
46
  "vite-tsconfig-paths": "^5.1.4",
47
47
  "vue-tsc": "3.1.5",
48
- "wrangler": "^4.51.0",
48
+ "wrangler": "^4.53.0",
49
49
  "zod": "^4.1.13"
50
50
  }
51
51
  }
@@ -1,3 +1,4 @@
1
+ import type { PluginOption } from 'vite'
1
2
  import path from 'node:path'
2
3
  import { cloudflare } from '@cloudflare/vite-plugin'
3
4
  import Tailwindcss from '@tailwindcss/vite'
@@ -6,6 +7,8 @@ import VueJsx from '@vitejs/plugin-vue-jsx'
6
7
  import VueRouter from 'unplugin-vue-router/vite'
7
8
  import { defineConfig } from 'vite'
8
9
  import VueDevTools from 'vite-plugin-vue-devtools'
10
+
11
+ const ensureVitePlugin = <T>(plugin: T) => plugin as unknown as PluginOption
9
12
  // https://vite.dev/config/
10
13
  export default defineConfig({
11
14
  resolve: {
@@ -15,18 +18,18 @@ export default defineConfig({
15
18
  },
16
19
  },
17
20
  plugins: [
18
- VueRouter(
19
- {
20
- dts: path.resolve(import.meta.dirname, 'src/types/typed-router.d.ts'),
21
- },
21
+ ensureVitePlugin(
22
+ VueRouter(
23
+ {
24
+ dts: path.resolve(import.meta.dirname, 'src/types/typed-router.d.ts'),
25
+ },
26
+ ),
22
27
  ),
23
- Vue(),
24
- // @ts-ignore
25
- VueJsx(),
26
- Tailwindcss(),
27
- // @ts-ignore
28
- cloudflare(),
29
- VueDevTools(),
28
+ ensureVitePlugin(Vue()),
29
+ ensureVitePlugin(VueJsx()),
30
+ ensureVitePlugin(Tailwindcss()),
31
+ ensureVitePlugin(cloudflare()),
32
+ ensureVitePlugin(VueDevTools()),
30
33
  ],
31
34
  server: {
32
35
  // proxy: {
@@ -53,7 +53,7 @@
53
53
  "devDependencies": {
54
54
  "@hono/node-server": "^1.19.6",
55
55
  "hono": "^4.10.7",
56
- "wrangler": "^4.51.0",
56
+ "wrangler": "^4.53.0",
57
57
  "zod": "^4.1.13"
58
58
  }
59
59
  }
@@ -53,8 +53,16 @@ npx monorepo clean # 批量删除已勾选的子项目
53
53
  npx monorepo sync # 同步所有包到 npmmirror
54
54
  npx monorepo mirror # 写入 VS Code 镜像配置
55
55
  npx monorepo up # 从最新模板同步配置文件
56
+ npx monorepo ai create # 生成 Agentic 任务提示词模板(支持输出到文件,可用别名 ai new)
56
57
  ```
57
58
 
59
+ 示例:`npx monorepo ai create -o agentic-task.md -f`,可直接生成 Markdown 模板并覆盖旧文件。默认会写入 `agentic/prompts/<timestamp>/prompt.md`,同时生成一个按时间排序的目录,并会提示你确认或修改目录名称,方便后续补充图片等素材;也可以用别名 `npx monorepo ai new`.
60
+
61
+ 多文件场景:
62
+
63
+ - `npx monorepo ai create --name checkout` 自动落盘到 `agentic/prompts/checkout.md`(默认目录可改)。
64
+ - `npx monorepo ai create --tasks agentic/tasks.json -f` 读取 JSON 数组批量生成,适合多人协作收口任务。
65
+
58
66
  所有命令都支持在 `monorepo.config.ts` 中覆写默认行为,例如新增模板、修改同步命令、跳过 README 初始化等。配置示例见下文和 [配置中心说明](./monorepo/manage.md#使用-monorepo-configts-定制命令行为)。
59
67
 
60
68
  ## 自定义配置:`monorepo.config.ts`
@@ -64,6 +72,12 @@ import { defineMonorepoConfig } from '@icebreakers/monorepo'
64
72
 
65
73
  export default defineMonorepoConfig({
66
74
  commands: {
75
+ ai: {
76
+ baseDir: 'agentic/custom-prompts',
77
+ format: 'json',
78
+ force: true,
79
+ tasksFile: 'agentic/tasks.json',
80
+ },
67
81
  create: {
68
82
  defaultTemplate: 'cli',
69
83
  renameJson: true,
@@ -83,14 +83,15 @@ export default defineMonorepoConfig({
83
83
 
84
84
  常用配置项:
85
85
 
86
- | 命令 | 可覆盖字段 | 说明 |
87
- | --------- | ---------------------------------------------------------------------------------- | ------------------------------ |
88
- | `create` | `templatesDir` / `templateMap` / `choices` / `defaultTemplate` | 扩展模板来源、修改提示内容 |
89
- | `clean` | `autoConfirm` / `ignorePackages` / `includePrivate` / `pinnedVersion` | 控制交互、过滤包、锁定依赖版本 |
90
- | `sync` | `concurrency` / `command` / `packages` | 定义同步命令与并发度 |
91
- | `upgrade` | `targets` / `mergeTargets` / `scripts` / `skipChangesetMarkdown` / `skipOverwrite` | 改写配置同步策略 |
92
- | `init` | `skipReadme` / `skipPkgJson` / `skipChangeset` | 按需跳过初始化步骤 |
93
- | `mirror` | `env` | 注入镜像环境变量 |
86
+ | 命令 | 可覆盖字段 | 说明 |
87
+ | --------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
88
+ | `create` | `templatesDir` / `templateMap` / `choices` / `defaultTemplate` | 扩展模板来源、修改提示内容 |
89
+ | `clean` | `autoConfirm` / `ignorePackages` / `includePrivate` / `pinnedVersion` | 控制交互、过滤包、锁定依赖版本 |
90
+ | `sync` | `concurrency` / `command` / `packages` | 定义同步命令与并发度 |
91
+ | `upgrade` | `targets` / `mergeTargets` / `scripts` / `skipChangesetMarkdown` / `skipOverwrite` | 改写配置同步策略 |
92
+ | `init` | `skipReadme` / `skipPkgJson` / `skipChangeset` | 按需跳过初始化步骤 |
93
+ | `mirror` | `env` | 注入镜像环境变量 |
94
+ | `ai` | `output` / `format` / `force` / `baseDir` / `tasksFile` | 预设 Agentic 模板输出目录、格式与批量任务,默认写入 `agentic/prompts/<timestamp>/prompt.md` |
94
95
 
95
96
  更多细节可参考 CLI 命令文档或源码中的 `commands/*`。
96
97
 
@@ -21,6 +21,9 @@
21
21
  "lint": "eslint .",
22
22
  "lint:fix": "eslint . --fix"
23
23
  },
24
+ "dependencies": {
25
+ "vue": "^3.5.25"
26
+ },
24
27
  "devDependencies": {
25
28
  "@braintree/sanitize-url": "^7.1.1",
26
29
  "@tailwindcss/vite": "^4.1.17",
@@ -28,7 +31,7 @@
28
31
  "cytoscape-cose-bilkent": "^4.1.0",
29
32
  "dayjs": "^1.11.19",
30
33
  "debug": "^4.4.3",
31
- "mermaid": "^11.12.1",
34
+ "mermaid": "^11.12.2",
32
35
  "tailwindcss": "^4.1.17",
33
36
  "vitepress": "^1.6.4",
34
37
  "vitepress-plugin-mermaid": "^2.0.17"
@@ -51,8 +51,8 @@
51
51
  "@vue/tsconfig": "^0.8.1",
52
52
  "jsdom": "^27.2.0",
53
53
  "tailwindcss": "^4.1.17",
54
- "unplugin-vue-router": "^0.18.0",
55
- "vite": "^7.2.4",
54
+ "unplugin-vue-router": "^0.19.0",
55
+ "vite": "^7.2.6",
56
56
  "vite-plugin-dts": "^4.5.4",
57
57
  "vue": "^3.5.25",
58
58
  "vue-router": "^4.6.3",
@@ -1,4 +1,4 @@
1
- import type { UserConfig } from 'vite'
1
+ import type { PluginOption, UserConfig } from 'vite'
2
2
  import Tailwindcss from '@tailwindcss/vite'
3
3
  import Vue from '@vitejs/plugin-vue'
4
4
  import path from 'pathe'
@@ -7,21 +7,28 @@ import { mergeConfig } from 'vite'
7
7
  import DTS from 'vite-plugin-dts'
8
8
  import { sharedConfig } from './vite.shared.config'
9
9
 
10
+ // 某些插件仍引用旧版 Vite 类型,这里统一断言到当前工程使用的 PluginOption,避免类型不兼容。
11
+ const ensureVitePlugin = <T>(plugin: T) => plugin as unknown as PluginOption
12
+
10
13
  export default mergeConfig(sharedConfig, {
11
14
  plugins: [
12
- VueRouter(
13
- {
14
- dts: path.relative(import.meta.dirname, './types/typed-router.d.ts'),
15
- },
15
+ ensureVitePlugin(
16
+ VueRouter(
17
+ {
18
+ dts: path.relative(import.meta.dirname, './types/typed-router.d.ts'),
19
+ },
20
+ ),
16
21
  ),
17
- Vue(),
18
- DTS(
19
- {
20
- tsconfigPath: './tsconfig.app.json',
21
- entryRoot: './lib',
22
- },
22
+ ensureVitePlugin(Vue()),
23
+ ensureVitePlugin(
24
+ DTS(
25
+ {
26
+ tsconfigPath: './tsconfig.app.json',
27
+ entryRoot: './lib',
28
+ },
29
+ ),
23
30
  ),
24
- Tailwindcss(),
31
+ ensureVitePlugin(Tailwindcss()),
25
32
  ],
26
33
  // https://vite.dev/guide/build.html#library-mode
27
34
  build: {