@icebreakers/monorepo 3.2.10 → 3.2.12

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/dist/cli.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_upgrade = require('./upgrade-CUCnIgN-.cjs');
1
+ const require_upgrade = require('./upgrade-DR2Sqzg5.cjs');
2
2
  let node_process = require("node:process");
3
3
  node_process = require_upgrade.__toESM(node_process);
4
4
  let _icebreakers_monorepo_templates = require("@icebreakers/monorepo-templates");
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as syncSkills, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, _ as getCreateChoices, b as cleanProjects, g as defaultTemplate, h as createNewProject, i as init, k as version, n as syncNpmMirror, r as setVscodeBinaryMirror, t as upgradeMonorepo } from "./upgrade-DxiYiN3S.mjs";
1
+ import { C as syncSkills, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, _ as getCreateChoices, b as cleanProjects, g as defaultTemplate, h as createNewProject, i as init, k as version, n as syncNpmMirror, r as setVscodeBinaryMirror, t as upgradeMonorepo } from "./upgrade-CPqyPuV5.mjs";
2
2
  import process from "node:process";
3
3
  import { input, program, select } from "@icebreakers/monorepo-templates";
4
4
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_upgrade = require('./upgrade-CUCnIgN-.cjs');
2
+ const require_upgrade = require('./upgrade-DR2Sqzg5.cjs');
3
3
  let _icebreakers_monorepo_templates = require("@icebreakers/monorepo-templates");
4
4
 
5
5
  exports.GitClient = require_upgrade.GitClient;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { A as defineMonorepoConfig, B as getWorkspacePackages, C as syncSkills, D as templatesDir, E as rootDir, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, T as packageDir, V as GitClient, _ as getCreateChoices, a as escapeStringRegexp, b as cleanProjects, c as isFileChanged, d as toWorkspaceGitignorePath, f as updateIssueTemplateConfig, h as createNewProject, i as init, j as loadMonorepoConfig, k as version, l as isGitignoreFile, m as createContext, n as syncNpmMirror, o as isMatch, p as isIgnorableFsError, r as setVscodeBinaryMirror, s as getFileHash, t as upgradeMonorepo, u as toPublishGitignorePath, v as getTemplateMap, w as assetsDir, x as getSkillTargetPaths, y as templateMap, z as getWorkspaceData } from "./upgrade-DxiYiN3S.mjs";
1
+ import { A as defineMonorepoConfig, B as getWorkspacePackages, C as syncSkills, D as templatesDir, E as rootDir, F as generateAgenticTemplate, I as generateAgenticTemplates, L as loadAgenticTasks, M as resolveCommandConfig, N as createTimestampFolderName, O as name, P as defaultAgenticBaseDir, R as logger, S as skillTargets, T as packageDir, V as GitClient, _ as getCreateChoices, a as escapeStringRegexp, b as cleanProjects, c as isFileChanged, d as toWorkspaceGitignorePath, f as updateIssueTemplateConfig, h as createNewProject, i as init, j as loadMonorepoConfig, k as version, l as isGitignoreFile, m as createContext, n as syncNpmMirror, o as isMatch, p as isIgnorableFsError, r as setVscodeBinaryMirror, s as getFileHash, t as upgradeMonorepo, u as toPublishGitignorePath, v as getTemplateMap, w as assetsDir, x as getSkillTargetPaths, y as templateMap, z as getWorkspaceData } from "./upgrade-CPqyPuV5.mjs";
2
2
 
3
3
  export { GitClient, assetsDir, cleanProjects, createContext, createNewProject, createTimestampFolderName, defaultAgenticBaseDir, defineMonorepoConfig, escapeStringRegexp, generateAgenticTemplate, generateAgenticTemplates, getCreateChoices, getFileHash, getSkillTargetPaths, getTemplateMap, getWorkspaceData, getWorkspacePackages, init, isFileChanged, isGitignoreFile, isIgnorableFsError, isMatch, loadAgenticTasks, loadMonorepoConfig, logger, name, packageDir, resolveCommandConfig, rootDir, setVscodeBinaryMirror, skillTargets, syncNpmMirror, syncSkills, templateMap, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath, updateIssueTemplateConfig, upgradeMonorepo, version };
@@ -7,7 +7,7 @@ import path from "pathe";
7
7
  import process from "node:process";
8
8
  import fs from "fs-extra";
9
9
  import { createConsola } from "consola";
10
- import { assetsDir, checkbox, execaCommand, getAssetTargets, isGitignoreFile, scaffoldTemplate, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
10
+ import { assetsDir, checkbox, ensureTemplateAssetsPrepared, execaCommand, getAssetTargets, isGitignoreFile, scaffoldTemplate, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
11
11
  import { loadConfig } from "c12";
12
12
  import os from "node:os";
13
13
  import * as path$1 from "node:path";
@@ -559,7 +559,7 @@ async function resolveCommandConfig(name, cwd) {
559
559
  //#endregion
560
560
  //#region package.json
561
561
  var name = "@icebreakers/monorepo";
562
- var version = "3.2.10";
562
+ var version = "3.2.12";
563
563
 
564
564
  //#endregion
565
565
  //#region src/constants.ts
@@ -664,11 +664,13 @@ async function cleanProjects(cwd, overrides) {
664
664
  });
665
665
  const readmeZh = path.resolve(workspaceDir, "README.zh-CN.md");
666
666
  const qoderDir = path.resolve(workspaceDir, ".qoder");
667
+ const docsPlansDir = path.resolve(workspaceDir, "docs/plans");
667
668
  const skillTargets = Object.values(getSkillTargetPaths());
668
669
  const candidates = Array.from(new Set([
669
670
  ...cleanDirs.filter(Boolean),
670
671
  readmeZh,
671
672
  qoderDir,
673
+ docsPlansDir,
672
674
  ...skillTargets
673
675
  ]));
674
676
  await Promise.all(candidates.map(async (dir) => {
@@ -1160,6 +1162,104 @@ async function syncNpmMirror(cwd, options) {
1160
1162
  await Promise.all(tasks);
1161
1163
  }
1162
1164
 
1165
+ //#endregion
1166
+ //#region src/commands/upgrade/agents.ts
1167
+ function normalizeEol(input) {
1168
+ return input.replace(/\r\n/g, "\n");
1169
+ }
1170
+ function normalizeComparableContent(input) {
1171
+ return normalizeEol(input).trimEnd();
1172
+ }
1173
+ function normalizeHeadingKey(line) {
1174
+ return line.replace(/^##\s+/, "").trim().toLowerCase();
1175
+ }
1176
+ function trimEdgeEmptyLines(lines) {
1177
+ const next = [...lines];
1178
+ while (next.length) {
1179
+ const first = next[0];
1180
+ if (first === void 0 || first.trim().length > 0) break;
1181
+ next.shift();
1182
+ }
1183
+ while (next.length) {
1184
+ const last = next.at(-1);
1185
+ if (last === void 0 || last.trim().length > 0) break;
1186
+ next.pop();
1187
+ }
1188
+ return next;
1189
+ }
1190
+ function parseMarkdownByH2(content) {
1191
+ const lines = normalizeEol(content).split("\n");
1192
+ const preamble = [];
1193
+ const sections = [];
1194
+ let current;
1195
+ for (const line of lines) {
1196
+ if (/^##\s+/.test(line)) {
1197
+ if (current) sections.push(current);
1198
+ current = {
1199
+ key: normalizeHeadingKey(line),
1200
+ lines: [line]
1201
+ };
1202
+ continue;
1203
+ }
1204
+ if (current) {
1205
+ current.lines.push(line);
1206
+ continue;
1207
+ }
1208
+ preamble.push(line);
1209
+ }
1210
+ if (current) sections.push(current);
1211
+ return {
1212
+ preamble,
1213
+ sections
1214
+ };
1215
+ }
1216
+ function mergePlainText(source, target) {
1217
+ const sourceLines = trimEdgeEmptyLines(normalizeEol(source).split("\n"));
1218
+ const result = trimEdgeEmptyLines(normalizeEol(target).split("\n"));
1219
+ const seen = new Set(result);
1220
+ for (const line of sourceLines) {
1221
+ if (!line.trim()) continue;
1222
+ if (seen.has(line)) continue;
1223
+ seen.add(line);
1224
+ result.push(line);
1225
+ }
1226
+ return `${result.join("\n")}\n`;
1227
+ }
1228
+ function getSectionSignature(section) {
1229
+ return `${section.key}\n${trimEdgeEmptyLines(section.lines).join("\n")}`;
1230
+ }
1231
+ /**
1232
+ * Merge AGENTS instructions by keeping existing sections and filling missing sections
1233
+ * from source defaults. This avoids destructive overwrite while still syncing updates.
1234
+ */
1235
+ function mergeAgentsMarkdown(source, target) {
1236
+ const sourceParsed = parseMarkdownByH2(source);
1237
+ const targetParsed = parseMarkdownByH2(target);
1238
+ if (!sourceParsed.sections.length || !targetParsed.sections.length) return mergePlainText(source, target);
1239
+ const sourceSectionKeys = new Set(sourceParsed.sections.map((section) => section.key));
1240
+ const targetSectionMap = new Map(targetParsed.sections.map((section) => [section.key, section]));
1241
+ const mergedSections = [];
1242
+ for (const section of sourceParsed.sections) mergedSections.push(targetSectionMap.get(section.key) ?? section);
1243
+ const seenTargetOnlySectionSignatures = /* @__PURE__ */ new Set();
1244
+ for (const section of targetParsed.sections) if (!sourceSectionKeys.has(section.key)) {
1245
+ const signature = getSectionSignature(section);
1246
+ if (seenTargetOnlySectionSignatures.has(signature)) continue;
1247
+ seenTargetOnlySectionSignatures.add(signature);
1248
+ mergedSections.push(section);
1249
+ }
1250
+ const preamble = trimEdgeEmptyLines(targetParsed.preamble.length ? targetParsed.preamble : sourceParsed.preamble);
1251
+ const blocks = [];
1252
+ if (preamble.length) blocks.push(preamble.join("\n"));
1253
+ for (const section of mergedSections) blocks.push(trimEdgeEmptyLines(section.lines).join("\n"));
1254
+ return `${blocks.filter(Boolean).join("\n\n")}\n`;
1255
+ }
1256
+ /**
1257
+ * Compare AGENTS markdown with normalized EOL and trailing newline differences ignored.
1258
+ */
1259
+ function isAgentsMarkdownEquivalent(left, right) {
1260
+ return normalizeComparableContent(left) === normalizeComparableContent(right);
1261
+ }
1262
+
1163
1263
  //#endregion
1164
1264
  //#region src/commands/upgrade/overwrite.ts
1165
1265
  function asBuffer(data) {
@@ -1365,6 +1465,7 @@ function mergeWorkspaceManifest(source, target) {
1365
1465
  * 将 assets 目录的模版文件同步到工程中,实现一键升级脚手架能力。
1366
1466
  */
1367
1467
  async function upgradeMonorepo(opts) {
1468
+ await ensureTemplateAssetsPrepared();
1368
1469
  const cwd = opts.cwd ?? process.cwd();
1369
1470
  const upgradeConfig = await resolveCommandConfig("upgrade", cwd);
1370
1471
  const merged = {
@@ -1450,6 +1551,25 @@ async function upgradeMonorepo(opts) {
1450
1551
  });
1451
1552
  continue;
1452
1553
  }
1554
+ if (relPath === "AGENTS.md") {
1555
+ const source = await fs.readFile(file.path, "utf8");
1556
+ const exists = await fs.pathExists(targetPath);
1557
+ const target = exists ? await fs.readFile(targetPath, "utf8") : "";
1558
+ const data = exists ? mergeAgentsMarkdown(source, target) : source;
1559
+ if (exists && isAgentsMarkdownEquivalent(target, data)) continue;
1560
+ const intent = await evaluateWriteIntent(targetPath, buildWriteIntentOptions(data));
1561
+ const action = async () => {
1562
+ await fs.outputFile(targetPath, data, "utf8");
1563
+ logger.success(targetPath);
1564
+ };
1565
+ await scheduleOverwrite(intent, {
1566
+ relPath,
1567
+ targetPath,
1568
+ action,
1569
+ pending: pendingOverwrites
1570
+ });
1571
+ continue;
1572
+ }
1453
1573
  if (relPath === ".changeset/config.json" && repoName) {
1454
1574
  const changesetJson = await fs.readJson(file.path);
1455
1575
  (0, import_set_value.default)(changesetJson, "changelog.1.repo", repoName);
@@ -570,7 +570,7 @@ async function resolveCommandConfig(name, cwd) {
570
570
  //#endregion
571
571
  //#region package.json
572
572
  var name = "@icebreakers/monorepo";
573
- var version = "3.2.10";
573
+ var version = "3.2.12";
574
574
 
575
575
  //#endregion
576
576
  //#region src/constants.ts
@@ -675,11 +675,13 @@ async function cleanProjects(cwd, overrides) {
675
675
  });
676
676
  const readmeZh = pathe.default.resolve(workspaceDir, "README.zh-CN.md");
677
677
  const qoderDir = pathe.default.resolve(workspaceDir, ".qoder");
678
+ const docsPlansDir = pathe.default.resolve(workspaceDir, "docs/plans");
678
679
  const skillTargets = Object.values(getSkillTargetPaths());
679
680
  const candidates = Array.from(new Set([
680
681
  ...cleanDirs.filter(Boolean),
681
682
  readmeZh,
682
683
  qoderDir,
684
+ docsPlansDir,
683
685
  ...skillTargets
684
686
  ]));
685
687
  await Promise.all(candidates.map(async (dir) => {
@@ -1171,6 +1173,104 @@ async function syncNpmMirror(cwd, options) {
1171
1173
  await Promise.all(tasks);
1172
1174
  }
1173
1175
 
1176
+ //#endregion
1177
+ //#region src/commands/upgrade/agents.ts
1178
+ function normalizeEol(input) {
1179
+ return input.replace(/\r\n/g, "\n");
1180
+ }
1181
+ function normalizeComparableContent(input) {
1182
+ return normalizeEol(input).trimEnd();
1183
+ }
1184
+ function normalizeHeadingKey(line) {
1185
+ return line.replace(/^##\s+/, "").trim().toLowerCase();
1186
+ }
1187
+ function trimEdgeEmptyLines(lines) {
1188
+ const next = [...lines];
1189
+ while (next.length) {
1190
+ const first = next[0];
1191
+ if (first === void 0 || first.trim().length > 0) break;
1192
+ next.shift();
1193
+ }
1194
+ while (next.length) {
1195
+ const last = next.at(-1);
1196
+ if (last === void 0 || last.trim().length > 0) break;
1197
+ next.pop();
1198
+ }
1199
+ return next;
1200
+ }
1201
+ function parseMarkdownByH2(content) {
1202
+ const lines = normalizeEol(content).split("\n");
1203
+ const preamble = [];
1204
+ const sections = [];
1205
+ let current;
1206
+ for (const line of lines) {
1207
+ if (/^##\s+/.test(line)) {
1208
+ if (current) sections.push(current);
1209
+ current = {
1210
+ key: normalizeHeadingKey(line),
1211
+ lines: [line]
1212
+ };
1213
+ continue;
1214
+ }
1215
+ if (current) {
1216
+ current.lines.push(line);
1217
+ continue;
1218
+ }
1219
+ preamble.push(line);
1220
+ }
1221
+ if (current) sections.push(current);
1222
+ return {
1223
+ preamble,
1224
+ sections
1225
+ };
1226
+ }
1227
+ function mergePlainText(source, target) {
1228
+ const sourceLines = trimEdgeEmptyLines(normalizeEol(source).split("\n"));
1229
+ const result = trimEdgeEmptyLines(normalizeEol(target).split("\n"));
1230
+ const seen = new Set(result);
1231
+ for (const line of sourceLines) {
1232
+ if (!line.trim()) continue;
1233
+ if (seen.has(line)) continue;
1234
+ seen.add(line);
1235
+ result.push(line);
1236
+ }
1237
+ return `${result.join("\n")}\n`;
1238
+ }
1239
+ function getSectionSignature(section) {
1240
+ return `${section.key}\n${trimEdgeEmptyLines(section.lines).join("\n")}`;
1241
+ }
1242
+ /**
1243
+ * Merge AGENTS instructions by keeping existing sections and filling missing sections
1244
+ * from source defaults. This avoids destructive overwrite while still syncing updates.
1245
+ */
1246
+ function mergeAgentsMarkdown(source, target) {
1247
+ const sourceParsed = parseMarkdownByH2(source);
1248
+ const targetParsed = parseMarkdownByH2(target);
1249
+ if (!sourceParsed.sections.length || !targetParsed.sections.length) return mergePlainText(source, target);
1250
+ const sourceSectionKeys = new Set(sourceParsed.sections.map((section) => section.key));
1251
+ const targetSectionMap = new Map(targetParsed.sections.map((section) => [section.key, section]));
1252
+ const mergedSections = [];
1253
+ for (const section of sourceParsed.sections) mergedSections.push(targetSectionMap.get(section.key) ?? section);
1254
+ const seenTargetOnlySectionSignatures = /* @__PURE__ */ new Set();
1255
+ for (const section of targetParsed.sections) if (!sourceSectionKeys.has(section.key)) {
1256
+ const signature = getSectionSignature(section);
1257
+ if (seenTargetOnlySectionSignatures.has(signature)) continue;
1258
+ seenTargetOnlySectionSignatures.add(signature);
1259
+ mergedSections.push(section);
1260
+ }
1261
+ const preamble = trimEdgeEmptyLines(targetParsed.preamble.length ? targetParsed.preamble : sourceParsed.preamble);
1262
+ const blocks = [];
1263
+ if (preamble.length) blocks.push(preamble.join("\n"));
1264
+ for (const section of mergedSections) blocks.push(trimEdgeEmptyLines(section.lines).join("\n"));
1265
+ return `${blocks.filter(Boolean).join("\n\n")}\n`;
1266
+ }
1267
+ /**
1268
+ * Compare AGENTS markdown with normalized EOL and trailing newline differences ignored.
1269
+ */
1270
+ function isAgentsMarkdownEquivalent(left, right) {
1271
+ return normalizeComparableContent(left) === normalizeComparableContent(right);
1272
+ }
1273
+
1174
1274
  //#endregion
1175
1275
  //#region src/commands/upgrade/overwrite.ts
1176
1276
  function asBuffer(data) {
@@ -1376,6 +1476,7 @@ function mergeWorkspaceManifest(source, target) {
1376
1476
  * 将 assets 目录的模版文件同步到工程中,实现一键升级脚手架能力。
1377
1477
  */
1378
1478
  async function upgradeMonorepo(opts) {
1479
+ await (0, _icebreakers_monorepo_templates.ensureTemplateAssetsPrepared)();
1379
1480
  const cwd = opts.cwd ?? node_process.default.cwd();
1380
1481
  const upgradeConfig = await resolveCommandConfig("upgrade", cwd);
1381
1482
  const merged = {
@@ -1461,6 +1562,25 @@ async function upgradeMonorepo(opts) {
1461
1562
  });
1462
1563
  continue;
1463
1564
  }
1565
+ if (relPath === "AGENTS.md") {
1566
+ const source = await fs_extra.default.readFile(file.path, "utf8");
1567
+ const exists = await fs_extra.default.pathExists(targetPath);
1568
+ const target = exists ? await fs_extra.default.readFile(targetPath, "utf8") : "";
1569
+ const data = exists ? mergeAgentsMarkdown(source, target) : source;
1570
+ if (exists && isAgentsMarkdownEquivalent(target, data)) continue;
1571
+ const intent = await evaluateWriteIntent(targetPath, buildWriteIntentOptions(data));
1572
+ const action = async () => {
1573
+ await fs_extra.default.outputFile(targetPath, data, "utf8");
1574
+ logger.success(targetPath);
1575
+ };
1576
+ await scheduleOverwrite(intent, {
1577
+ relPath,
1578
+ targetPath,
1579
+ action,
1580
+ pending: pendingOverwrites
1581
+ });
1582
+ continue;
1583
+ }
1464
1584
  if (relPath === ".changeset/config.json" && repoName) {
1465
1585
  const changesetJson = await fs_extra.default.readJson(file.path);
1466
1586
  (0, import_set_value.default)(changesetJson, "changelog.1.repo", repoName);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@icebreakers/monorepo",
3
3
  "type": "module",
4
- "version": "3.2.10",
4
+ "version": "3.2.12",
5
5
  "description": "The icebreaker's monorepo manager",
6
6
  "author": "ice breaker <hi@sonofmagic.top>",
7
7
  "license": "MIT",
@@ -60,8 +60,8 @@
60
60
  "@pnpm/find-workspace-dir": "^1000.1.4",
61
61
  "@pnpm/logger": "^1001.0.1",
62
62
  "@pnpm/types": "^1001.3.0",
63
- "@pnpm/worker": "^1000.6.4",
64
- "@pnpm/workspace.find-packages": "^1000.0.59",
63
+ "@pnpm/worker": "^1000.6.5",
64
+ "@pnpm/workspace.find-packages": "^1000.0.62",
65
65
  "@pnpm/workspace.read-manifest": "^1000.2.10",
66
66
  "c12": "^3.3.3",
67
67
  "comment-json": "^4.5.1",
@@ -73,9 +73,9 @@
73
73
  "pathe": "^2.0.3",
74
74
  "picocolors": "^1.1.1",
75
75
  "semver": "^7.7.4",
76
- "simple-git": "^3.30.0",
76
+ "simple-git": "^3.32.3",
77
77
  "yaml": "^2.8.2",
78
- "@icebreakers/monorepo-templates": "0.1.10"
78
+ "@icebreakers/monorepo-templates": "0.1.11"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/klaw": "^3.0.7",