@icebreakers/monorepo 3.2.14 → 3.2.16

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.
@@ -5,112 +5,22 @@ import { findWorkspacePackages } from "@pnpm/workspace.find-packages";
5
5
  import { readWorkspaceManifest } from "@pnpm/workspace.read-manifest";
6
6
  import path from "pathe";
7
7
  import process from "node:process";
8
- import fs from "fs-extra";
8
+ import { access, cp, mkdir, mkdtemp, open, readFile, rm, stat, writeFile } from "node:fs/promises";
9
9
  import { createConsola } from "consola";
10
10
  import { assetsDir, checkbox, ensureTemplateAssetsPrepared, execaCommand, getAssetTargets, isGitignoreFile, scaffoldTemplate, templatesDir, toPublishGitignorePath, toWorkspaceGitignorePath } from "@icebreakers/monorepo-templates";
11
+ import YAML, { isSeq, parseDocument } from "yaml";
12
+ import crypto from "node:crypto";
11
13
  import { loadConfig } from "c12";
12
14
  import os from "node:os";
13
15
  import * as path$1 from "node:path";
14
16
  import { fileURLToPath } from "node:url";
15
17
  import pc from "picocolors";
16
18
  import "@pnpm/types";
17
- import YAML, { isSeq, parseDocument } from "yaml";
18
- import crypto from "node:crypto";
19
19
  import { parse, stringify } from "comment-json";
20
20
  import PQueue from "p-queue";
21
21
  import klaw from "klaw";
22
- import { Buffer as Buffer$1 } from "node:buffer";
22
+ import { Buffer } from "node:buffer";
23
23
  import { coerce, gte, minVersion } from "semver";
24
- //#region \0rolldown/runtime.js
25
- var __create = Object.create;
26
- var __defProp$1 = Object.defineProperty;
27
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
28
- var __getOwnPropNames = Object.getOwnPropertyNames;
29
- var __getProtoOf = Object.getPrototypeOf;
30
- var __hasOwnProp = Object.prototype.hasOwnProperty;
31
- var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
32
- var __copyProps = (to, from, except, desc) => {
33
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
34
- key = keys[i];
35
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp$1(to, key, {
36
- get: ((k) => from[k]).bind(null, key),
37
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
38
- });
39
- }
40
- return to;
41
- };
42
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
43
- value: mod,
44
- enumerable: true
45
- }) : target, mod));
46
- //#endregion
47
- //#region ../../node_modules/.pnpm/get-value@4.0.1/node_modules/get-value/dist/index.mjs
48
- var __defProp = Object.defineProperty;
49
- var __name = (target, value) => __defProp(target, "name", {
50
- value,
51
- configurable: true
52
- });
53
- var isObject = /* @__PURE__ */ __name((v) => v !== null && typeof v === "object", "isObject");
54
- var join = /* @__PURE__ */ __name((segs, joinChar, options) => {
55
- if (typeof options.join === "function") return options.join(segs);
56
- return segs[0] + joinChar + segs[1];
57
- }, "join");
58
- var split = /* @__PURE__ */ __name((path, splitChar, options) => {
59
- if (typeof options.split === "function") return options.split(path);
60
- return path.split(splitChar);
61
- }, "split");
62
- var isValid = /* @__PURE__ */ __name((key, target = {}, options) => {
63
- if (typeof options?.isValid === "function") return options.isValid(key, target);
64
- return true;
65
- }, "isValid");
66
- var isValidObject = /* @__PURE__ */ __name((v) => {
67
- return isObject(v) || typeof v === "function";
68
- }, "isValidObject");
69
- var index_default = /* @__PURE__ */ __name((target, path, options = {}) => {
70
- if (!isObject(options)) options = { default: options };
71
- if (!isValidObject(target)) return typeof options.default !== "undefined" ? options.default : target;
72
- if (typeof path === "number") path = String(path);
73
- const pathIsArray = Array.isArray(path);
74
- const pathIsString = typeof path === "string";
75
- const splitChar = options.separator || ".";
76
- const joinChar = options.joinChar || (typeof splitChar === "string" ? splitChar : ".");
77
- if (!pathIsString && !pathIsArray) return target;
78
- if (target[path] !== void 0) return isValid(path, target, options) ? target[path] : options.default;
79
- const segs = pathIsArray ? path : split(path, splitChar, options);
80
- const len = segs.length;
81
- let idx = 0;
82
- do {
83
- let prop = segs[idx];
84
- if (typeof prop !== "string") prop = String(prop);
85
- while (prop && prop.slice(-1) === "\\") prop = join([prop.slice(0, -1), segs[++idx] || ""], joinChar, options);
86
- if (target[prop] !== void 0) {
87
- if (!isValid(prop, target, options)) return options.default;
88
- target = target[prop];
89
- } else {
90
- let hasProp = false;
91
- let n = idx + 1;
92
- while (n < len) {
93
- prop = join([prop, segs[n++]], joinChar, options);
94
- if (hasProp = target[prop] !== void 0) {
95
- if (!isValid(prop, target, options)) return options.default;
96
- target = target[prop];
97
- idx = n - 1;
98
- break;
99
- }
100
- }
101
- if (!hasProp) return options.default;
102
- }
103
- } while (++idx < len && isValidObject(target));
104
- if (idx === len) return target;
105
- return options.default;
106
- }, "getValue");
107
- /*!
108
- * get-value <https://github.com/jonschlinkert/get-value>
109
- *
110
- * Copyright (c) 2014-present, Jon Schlinkert.
111
- * Released under the MIT License.
112
- */
113
- //#endregion
114
24
  //#region src/core/git.ts
115
25
  /**
116
26
  * 对 simple-git 的轻量封装,集中处理配置缓存与常用查询。
@@ -145,8 +55,8 @@ var GitClient = class {
145
55
  * 解析 remote.origin.url,返回 git-url-parse 的结构,便于获取仓库元信息。
146
56
  */
147
57
  async getGitUrl() {
148
- const x = index_default(await this.getConfig(), "remote.origin.url");
149
- if (x) return gitUrlParse(x);
58
+ const x = (await this.getConfig())["remote.origin.url"];
59
+ if (typeof x === "string") return gitUrlParse(x);
150
60
  }
151
61
  /**
152
62
  * 组合 owner/name,生成常用的仓库名表达。
@@ -161,8 +71,8 @@ var GitClient = class {
161
71
  async getUser() {
162
72
  const config = await this.getConfig();
163
73
  return {
164
- name: index_default(config, "user.name"),
165
- email: index_default(config, "user.email")
74
+ name: config["user.name"],
75
+ email: config["user.email"]
166
76
  };
167
77
  }
168
78
  /**
@@ -256,6 +166,90 @@ async function getWorkspaceData(cwd, options) {
256
166
  };
257
167
  }
258
168
  //#endregion
169
+ //#region src/utils/fs.ts
170
+ function stringifyJson(data, options) {
171
+ return JSON.stringify(data, void 0, options?.spaces);
172
+ }
173
+ async function ensureParentDir(targetPath) {
174
+ await mkdir(path.dirname(targetPath), { recursive: true });
175
+ }
176
+ async function pathExists(targetPath) {
177
+ try {
178
+ await access(targetPath);
179
+ return true;
180
+ } catch {
181
+ return false;
182
+ }
183
+ }
184
+ const exists = pathExists;
185
+ async function ensureDir(targetPath) {
186
+ await mkdir(targetPath, { recursive: true });
187
+ }
188
+ async function ensureFile(targetPath) {
189
+ await ensureParentDir(targetPath);
190
+ await (await open(targetPath, "a")).close();
191
+ }
192
+ async function remove(targetPath) {
193
+ await rm(targetPath, {
194
+ recursive: true,
195
+ force: true,
196
+ maxRetries: 3,
197
+ retryDelay: 100
198
+ });
199
+ }
200
+ async function copy(sourcePath, targetPath) {
201
+ await cp(sourcePath, targetPath, {
202
+ recursive: true,
203
+ force: true
204
+ });
205
+ }
206
+ async function outputFile(targetPath, data, options) {
207
+ await ensureParentDir(targetPath);
208
+ await writeFile(targetPath, data, options);
209
+ }
210
+ async function readJson(targetPath) {
211
+ return JSON.parse(await readFile(targetPath, "utf8"));
212
+ }
213
+ const readJSON = readJson;
214
+ async function writeJson(targetPath, data, options) {
215
+ await writeFile(targetPath, stringifyJson(data, options), "utf8");
216
+ }
217
+ const writeJSON = writeJson;
218
+ async function outputJson(targetPath, data, options) {
219
+ await ensureParentDir(targetPath);
220
+ await writeJson(targetPath, data, options);
221
+ }
222
+ const outputJSON = outputJson;
223
+ /**
224
+ * 判断是否为可忽略的文件系统错误。
225
+ * - ENOENT: 文件已被删除
226
+ * - EBUSY: Windows 中资源被系统占用
227
+ */
228
+ function isIgnorableFsError(error) {
229
+ if (!error) return false;
230
+ const code = error.code;
231
+ return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
232
+ }
233
+ const fs = {
234
+ copy,
235
+ ensureDir,
236
+ ensureFile,
237
+ exists,
238
+ mkdtemp,
239
+ outputFile,
240
+ outputJSON,
241
+ outputJson,
242
+ pathExists,
243
+ readFile,
244
+ readJSON,
245
+ readJson,
246
+ remove,
247
+ stat,
248
+ writeFile,
249
+ writeJSON,
250
+ writeJson
251
+ };
252
+ //#endregion
259
253
  //#region src/core/logger.ts
260
254
  /**
261
255
  * 统一的日志实例,便于在命令行中输出带有前缀和颜色的消息。
@@ -332,169 +326,126 @@ async function generateAgenticTemplates(tasks, defaults = {}) {
332
326
  return results;
333
327
  }
334
328
  //#endregion
335
- //#region ../../node_modules/.pnpm/is-primitive@3.0.1/node_modules/is-primitive/index.js
336
- /*!
337
- * is-primitive <https://github.com/jonschlinkert/is-primitive>
338
- *
339
- * Copyright (c) 2014-present, Jon Schlinkert.
340
- * Released under the MIT License.
329
+ //#region src/utils/github.ts
330
+ /**
331
+ * Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
341
332
  */
342
- var require_is_primitive = /* @__PURE__ */ __commonJSMin(((exports, module) => {
343
- module.exports = function isPrimitive(val) {
344
- if (typeof val === "object") return val === null;
345
- return typeof val !== "function";
346
- };
347
- }));
333
+ function updateIssueTemplateConfig(source, repoName) {
334
+ if (!repoName) return source;
335
+ let doc;
336
+ try {
337
+ doc = parseDocument(source);
338
+ } catch {
339
+ return source;
340
+ }
341
+ const contactLinks = doc.get("contact_links");
342
+ if (!isSeq(contactLinks)) return source;
343
+ const nextUrl = `https://github.com/${repoName}/discussions`;
344
+ let changed = false;
345
+ contactLinks.items.forEach((_, index) => {
346
+ const url = doc.getIn([
347
+ "contact_links",
348
+ index,
349
+ "url"
350
+ ]);
351
+ if (typeof url !== "string") return;
352
+ if (!url.includes("/discussions")) return;
353
+ if (url === nextUrl) return;
354
+ doc.setIn([
355
+ "contact_links",
356
+ index,
357
+ "url"
358
+ ], nextUrl);
359
+ changed = true;
360
+ });
361
+ if (!changed) return source;
362
+ return doc.toString();
363
+ }
348
364
  //#endregion
349
- //#region ../../node_modules/.pnpm/isobject@3.0.1/node_modules/isobject/index.js
350
- /*!
351
- * isobject <https://github.com/jonschlinkert/isobject>
352
- *
353
- * Copyright (c) 2014-2017, Jon Schlinkert.
354
- * Released under the MIT License.
365
+ //#region src/utils/hash.ts
366
+ /**
367
+ * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
355
368
  */
356
- var require_isobject = /* @__PURE__ */ __commonJSMin(((exports, module) => {
357
- module.exports = function isObject(val) {
358
- return val != null && typeof val === "object" && Array.isArray(val) === false;
359
- };
360
- }));
361
- //#endregion
362
- //#region ../../node_modules/.pnpm/is-plain-object@2.0.4/node_modules/is-plain-object/index.js
363
- /*!
364
- * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
365
- *
366
- * Copyright (c) 2014-2017, Jon Schlinkert.
367
- * Released under the MIT License.
369
+ function getFileHash(data) {
370
+ const hashSum = crypto.createHash("md5");
371
+ hashSum.update(data);
372
+ return hashSum.digest("hex");
373
+ }
374
+ /**
375
+ * 对比两个文件的 md5,如果不一致则认为内容有变化。
368
376
  */
369
- var require_is_plain_object = /* @__PURE__ */ __commonJSMin(((exports, module) => {
370
- var isObject = require_isobject();
371
- function isObjectObject(o) {
372
- return isObject(o) === true && Object.prototype.toString.call(o) === "[object Object]";
377
+ function isFileChanged(src, dest) {
378
+ try {
379
+ return getFileHash(src) !== getFileHash(dest);
380
+ } catch (err) {
381
+ logger.error("Error calculating file hash:", err);
382
+ return false;
373
383
  }
374
- module.exports = function isPlainObject(o) {
375
- var ctor, prot;
376
- if (isObjectObject(o) === false) return false;
377
- ctor = o.constructor;
378
- if (typeof ctor !== "function") return false;
379
- prot = ctor.prototype;
380
- if (isObjectObject(prot) === false) return false;
381
- if (prot.hasOwnProperty("isPrototypeOf") === false) return false;
382
- return true;
383
- };
384
- }));
384
+ }
385
385
  //#endregion
386
- //#region ../../node_modules/.pnpm/set-value@4.1.0/node_modules/set-value/index.js
387
- /*!
388
- * set-value <https://github.com/jonschlinkert/set-value>
389
- *
390
- * Copyright (c) Jon Schlinkert (https://github.com/jonschlinkert).
391
- * Released under the MIT License.
392
- */
393
- var require_set_value = /* @__PURE__ */ __commonJSMin(((exports, module) => {
394
- const { deleteProperty } = Reflect;
395
- const isPrimitive = require_is_primitive();
396
- const isPlainObject = require_is_plain_object();
397
- const isObject = (value) => {
398
- return typeof value === "object" && value !== null || typeof value === "function";
399
- };
400
- const isUnsafeKey = (key) => {
401
- return key === "__proto__" || key === "constructor" || key === "prototype";
402
- };
403
- const validateKey = (key) => {
404
- if (!isPrimitive(key)) throw new TypeError("Object keys must be strings or symbols");
405
- if (isUnsafeKey(key)) throw new Error(`Cannot set unsafe key: "${key}"`);
406
- };
407
- const toStringKey = (input) => {
408
- return Array.isArray(input) ? input.flat().map(String).join(",") : input;
409
- };
410
- const createMemoKey = (input, options) => {
411
- if (typeof input !== "string" || !options) return input;
412
- let key = input + ";";
413
- if (options.arrays !== void 0) key += `arrays=${options.arrays};`;
414
- if (options.separator !== void 0) key += `separator=${options.separator};`;
415
- if (options.split !== void 0) key += `split=${options.split};`;
416
- if (options.merge !== void 0) key += `merge=${options.merge};`;
417
- if (options.preservePaths !== void 0) key += `preservePaths=${options.preservePaths};`;
418
- return key;
419
- };
420
- const memoize = (input, options, fn) => {
421
- const key = toStringKey(options ? createMemoKey(input, options) : input);
422
- validateKey(key);
423
- const value = setValue.cache.get(key) || fn();
424
- setValue.cache.set(key, value);
425
- return value;
426
- };
427
- const splitString = (input, options = {}) => {
428
- const sep = options.separator || ".";
429
- const preserve = sep === "/" ? false : options.preservePaths;
430
- if (typeof input === "string" && preserve !== false && /\//.test(input)) return [input];
431
- const parts = [];
432
- let part = "";
433
- const push = (part) => {
434
- let number;
435
- if (part.trim() !== "" && Number.isInteger(number = Number(part))) parts.push(number);
436
- else parts.push(part);
437
- };
438
- for (let i = 0; i < input.length; i++) {
439
- const value = input[i];
440
- if (value === "\\") {
441
- part += input[++i];
442
- continue;
443
- }
444
- if (value === sep) {
445
- push(part);
446
- part = "";
447
- continue;
448
- }
449
- part += value;
386
+ //#region src/utils/object.ts
387
+ const arrayIndexPattern = /^\d+$/;
388
+ function isArrayIndex(value) {
389
+ return arrayIndexPattern.test(value);
390
+ }
391
+ function parsePath(input) {
392
+ const segments = [];
393
+ let current = "";
394
+ let escaped = false;
395
+ for (const char of input) {
396
+ if (escaped) {
397
+ current += char;
398
+ escaped = false;
399
+ continue;
450
400
  }
451
- if (part) push(part);
452
- return parts;
453
- };
454
- const split = (input, options) => {
455
- if (options && typeof options.split === "function") return options.split(input);
456
- if (typeof input === "symbol") return [input];
457
- if (Array.isArray(input)) return input;
458
- return memoize(input, options, () => splitString(input, options));
459
- };
460
- const assignProp = (obj, prop, value, options) => {
461
- validateKey(prop);
462
- if (value === void 0) deleteProperty(obj, prop);
463
- else if (options && options.merge) {
464
- const merge = options.merge === "function" ? options.merge : Object.assign;
465
- if (merge && isPlainObject(obj[prop]) && isPlainObject(value)) obj[prop] = merge(obj[prop], value);
466
- else obj[prop] = value;
467
- } else obj[prop] = value;
468
- return obj;
469
- };
470
- const setValue = (target, path, value, options) => {
471
- if (!path || !isObject(target)) return target;
472
- const keys = split(path, options);
473
- let obj = target;
474
- for (let i = 0; i < keys.length; i++) {
475
- const key = keys[i];
476
- const next = keys[i + 1];
477
- validateKey(key);
478
- if (next === void 0) {
479
- assignProp(obj, key, value, options);
480
- break;
481
- }
482
- if (typeof next === "number" && !Array.isArray(obj[key])) {
483
- obj = obj[key] = [];
484
- continue;
485
- }
486
- if (!isObject(obj[key])) obj[key] = {};
487
- obj = obj[key];
401
+ if (char === "\\") {
402
+ escaped = true;
403
+ continue;
488
404
  }
489
- return target;
490
- };
491
- setValue.split = split;
492
- setValue.cache = /* @__PURE__ */ new Map();
493
- setValue.clear = () => {
494
- setValue.cache = /* @__PURE__ */ new Map();
495
- };
496
- module.exports = setValue;
497
- }));
405
+ if (char === ".") {
406
+ segments.push(current);
407
+ current = "";
408
+ continue;
409
+ }
410
+ current += char;
411
+ }
412
+ segments.push(current);
413
+ return segments;
414
+ }
415
+ function setByPath(target, path, value) {
416
+ const segments = typeof path === "string" ? parsePath(path) : [...path];
417
+ if (!segments.length) return target;
418
+ let current = target;
419
+ for (let index = 0; index < segments.length - 1; index++) {
420
+ const segment = segments[index];
421
+ const nextSegment = segments[index + 1];
422
+ const key = Array.isArray(current) && isArrayIndex(segment) ? Number(segment) : segment;
423
+ const existing = current[key];
424
+ if (typeof existing !== "object" || existing === null) current[key] = isArrayIndex(nextSegment) ? [] : {};
425
+ current = current[key];
426
+ }
427
+ const lastSegment = segments.at(-1);
428
+ const lastKey = Array.isArray(current) && isArrayIndex(lastSegment) ? Number(lastSegment) : lastSegment;
429
+ current[lastKey] = value;
430
+ return target;
431
+ }
432
+ //#endregion
433
+ //#region src/utils/regexp.ts
434
+ const regexpSpecialCharacterPattern = /[|\\{}()[\]^$+*?.]/g;
435
+ const hyphenPattern = /-/g;
436
+ /**
437
+ * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
438
+ */
439
+ function escapeStringRegexp(str) {
440
+ return str.replace(regexpSpecialCharacterPattern, "\\$&").replace(hyphenPattern, "\\x2d");
441
+ }
442
+ /**
443
+ * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
444
+ */
445
+ function isMatch(str, arr) {
446
+ for (const reg of arr) if (reg.test(str)) return true;
447
+ return false;
448
+ }
498
449
  //#endregion
499
450
  //#region src/core/config.ts
500
451
  /**
@@ -542,7 +493,7 @@ async function resolveCommandConfig(name, cwd) {
542
493
  //#endregion
543
494
  //#region package.json
544
495
  var name = "@icebreakers/monorepo";
545
- var version = "3.2.14";
496
+ var version = "3.2.16";
546
497
  //#endregion
547
498
  //#region src/constants.ts
548
499
  /**
@@ -604,7 +555,6 @@ async function syncSkills(options = {}) {
604
555
  }
605
556
  //#endregion
606
557
  //#region src/commands/clean.ts
607
- var import_set_value = /* @__PURE__ */ __toESM(require_set_value(), 1);
608
558
  function mergeCleanConfig(base, overrides) {
609
559
  const normalizedBase = base ?? {};
610
560
  if (!overrides) return normalizedBase;
@@ -658,7 +608,7 @@ async function cleanProjects(cwd, overrides) {
658
608
  }));
659
609
  const name = path.resolve(workspaceDir, "package.json");
660
610
  const pkgJson = await fs.readJson(name);
661
- (0, import_set_value.default)(pkgJson, "devDependencies.@icebreakers/monorepo", cleanConfig?.pinnedVersion ?? "latest", { preservePaths: false });
611
+ setByPath(pkgJson, "devDependencies.@icebreakers/monorepo", cleanConfig?.pinnedVersion ?? "latest");
662
612
  await fs.outputJson(name, pkgJson, { spaces: 2 });
663
613
  }
664
614
  //#endregion
@@ -765,7 +715,7 @@ async function applyGitMetadata(pkgJson, repoDir, targetDir) {
765
715
  const git = new GitClient({ baseDir: repoDir });
766
716
  const repoName = await git.getRepoName();
767
717
  if (!repoName) return;
768
- (0, import_set_value.default)(pkgJson, ["bugs", "url"], `https://github.com/${repoName}/issues`);
718
+ setByPath(pkgJson, ["bugs", "url"], `https://github.com/${repoName}/issues`);
769
719
  const repository = {
770
720
  type: "git",
771
721
  url: `git+https://github.com/${repoName}.git`
@@ -773,9 +723,9 @@ async function applyGitMetadata(pkgJson, repoDir, targetDir) {
773
723
  const directoryBase = await git.getRepoRoot() ?? repoDir;
774
724
  const relative = path.relative(directoryBase, targetDir);
775
725
  if (relative && relative !== ".") repository.directory = relative.split(path.sep).join("/");
776
- (0, import_set_value.default)(pkgJson, "repository", repository);
726
+ setByPath(pkgJson, "repository", repository);
777
727
  const gitUser = await git.getUser();
778
- if (gitUser?.name && gitUser?.email) (0, import_set_value.default)(pkgJson, "author", `${gitUser.name} <${gitUser.email}>`);
728
+ if (gitUser?.name && gitUser?.email) setByPath(pkgJson, "author", `${gitUser.name} <${gitUser.email}>`);
779
729
  } catch {}
780
730
  }
781
731
  /**
@@ -808,8 +758,8 @@ async function createNewProject(options) {
808
758
  });
809
759
  if (hasPackageJson) {
810
760
  const sourceJson = await fs.readJson(sourceJsonPath);
811
- (0, import_set_value.default)(sourceJson, "version", "0.0.0");
812
- (0, import_set_value.default)(sourceJson, "name", name?.startsWith("@") ? name : path.basename(targetName));
761
+ setByPath(sourceJson, "version", "0.0.0");
762
+ setByPath(sourceJson, "name", name?.startsWith("@") ? name : path.basename(targetName));
813
763
  await applyGitMetadata(sourceJson, cwd, to);
814
764
  await fs.outputJson(path.resolve(to, renameJson ? "package.mock.json" : "package.json"), sourceJson, { spaces: 2 });
815
765
  }
@@ -847,99 +797,13 @@ async function setChangeset_default(ctx) {
847
797
  if (await fs.exists(changesetConfigPath)) {
848
798
  const changesetConfig = await fs.readJson(changesetConfigPath);
849
799
  if (gitUrl.full_name) {
850
- (0, import_set_value.default)(changesetConfig, "changelog.1.repo", gitUrl.full_name);
800
+ setByPath(changesetConfig, "changelog.1.repo", gitUrl.full_name);
851
801
  await fs.outputJson(changesetConfigPath, changesetConfig, { spaces: 2 });
852
802
  }
853
803
  }
854
804
  }
855
805
  }
856
806
  //#endregion
857
- //#region src/utils/fs.ts
858
- /**
859
- * 判断是否为可忽略的文件系统错误。
860
- * - ENOENT: 文件已被删除
861
- * - EBUSY: Windows 中资源被系统占用
862
- */
863
- function isIgnorableFsError(error) {
864
- if (!error) return false;
865
- const code = error.code;
866
- return code === "ENOENT" || code === "EBUSY" || code === "EEXIST";
867
- }
868
- //#endregion
869
- //#region src/utils/github.ts
870
- /**
871
- * 将 Issue 模版里的 discussions 链接同步为当前仓库的 discussions 地址。
872
- */
873
- function updateIssueTemplateConfig(source, repoName) {
874
- if (!repoName) return source;
875
- let doc;
876
- try {
877
- doc = parseDocument(source);
878
- } catch {
879
- return source;
880
- }
881
- const contactLinks = doc.get("contact_links");
882
- if (!isSeq(contactLinks)) return source;
883
- const nextUrl = `https://github.com/${repoName}/discussions`;
884
- let changed = false;
885
- contactLinks.items.forEach((_, index) => {
886
- const url = doc.getIn([
887
- "contact_links",
888
- index,
889
- "url"
890
- ]);
891
- if (typeof url !== "string") return;
892
- if (!url.includes("/discussions")) return;
893
- if (url === nextUrl) return;
894
- doc.setIn([
895
- "contact_links",
896
- index,
897
- "url"
898
- ], nextUrl);
899
- changed = true;
900
- });
901
- if (!changed) return source;
902
- return doc.toString();
903
- }
904
- //#endregion
905
- //#region src/utils/hash.ts
906
- /**
907
- * 生成给定二进制内容的 md5 摘要,用于快速比较文件内容。
908
- */
909
- function getFileHash(data) {
910
- const hashSum = crypto.createHash("md5");
911
- hashSum.update(data);
912
- return hashSum.digest("hex");
913
- }
914
- /**
915
- * 对比两个文件的 md5,如果不一致则认为内容有变化。
916
- */
917
- function isFileChanged(src, dest) {
918
- try {
919
- return getFileHash(src) !== getFileHash(dest);
920
- } catch (err) {
921
- logger.error("Error calculating file hash:", err);
922
- return false;
923
- }
924
- }
925
- //#endregion
926
- //#region src/utils/regexp.ts
927
- const regexpSpecialCharacterPattern = /[|\\{}()[\]^$+*?.]/g;
928
- const hyphenPattern = /-/g;
929
- /**
930
- * 逃逸正则表达式中所有特殊字符,避免被当做模式解析。
931
- */
932
- function escapeStringRegexp(str) {
933
- return str.replace(regexpSpecialCharacterPattern, "\\$&").replace(hyphenPattern, "\\x2d");
934
- }
935
- /**
936
- * 判断字符串是否命中任意一个正则,用于过滤要同步的资产文件。
937
- */
938
- function isMatch(str, arr) {
939
- for (const reg of arr) if (reg.test(str)) return true;
940
- return false;
941
- }
942
- //#endregion
943
807
  //#region src/commands/init/setIssueTemplateConfig.ts
944
808
  /**
945
809
  * 同步 Issue 模版里的 discussions 链接到当前仓库。
@@ -965,14 +829,14 @@ async function setPkgJson_default(ctx) {
965
829
  if (!await fs.pathExists(pkg.pkgJsonPath)) return;
966
830
  const pkgJson = JSON.parse(JSON.stringify(pkg.manifest));
967
831
  const directory = path.relative(cwd, pkg.rootDir);
968
- (0, import_set_value.default)(pkgJson, ["bugs", "url"], `https://github.com/${gitUrl.full_name}/issues`);
832
+ setByPath(pkgJson, ["bugs", "url"], `https://github.com/${gitUrl.full_name}/issues`);
969
833
  const repository = {
970
834
  type: "git",
971
835
  url: `git+https://github.com/${gitUrl.full_name}.git`
972
836
  };
973
837
  if (directory) repository.directory = directory;
974
- (0, import_set_value.default)(pkgJson, "repository", repository);
975
- if (gitUser?.name && gitUser?.email) (0, import_set_value.default)(pkgJson, "author", `${gitUser.name} <${gitUser.email}>`);
838
+ setByPath(pkgJson, "repository", repository);
839
+ if (gitUser?.name && gitUser?.email) setByPath(pkgJson, "author", `${gitUser.name} <${gitUser.email}>`);
976
840
  const nextContent = `${JSON.stringify(pkgJson, void 0, 2)}\n`;
977
841
  if (await fs.readFile(pkg.pkgJsonPath, "utf8") !== nextContent) await fs.writeFile(pkg.pkgJsonPath, nextContent, "utf8");
978
842
  }));
@@ -1078,7 +942,7 @@ function setMirror(obj, envs = chinaMirrorsEnvs) {
1078
942
  "osx"
1079
943
  ];
1080
944
  const prefix = "terminal.integrated.env";
1081
- if (typeof obj === "object" && obj) for (const platform of platforms) (0, import_set_value.default)(obj, [prefix, platform].join(".").replaceAll(".", "\\."), envs);
945
+ if (typeof obj === "object" && obj) for (const platform of platforms) setByPath(obj, [prefix, platform].join(".").replaceAll(".", "\\."), envs);
1082
946
  }
1083
947
  //#endregion
1084
948
  //#region src/commands/mirror/binaryMirror.ts
@@ -1230,7 +1094,7 @@ function isAgentsMarkdownEquivalent(left, right) {
1230
1094
  //#endregion
1231
1095
  //#region src/commands/upgrade/overwrite.ts
1232
1096
  function asBuffer(data) {
1233
- return typeof data === "string" ? Buffer$1.from(data) : data;
1097
+ return typeof data === "string" ? Buffer.from(data) : data;
1234
1098
  }
1235
1099
  async function evaluateWriteIntent(targetPath, options) {
1236
1100
  const { skipOverwrite, source } = options;
@@ -1578,7 +1442,7 @@ async function upgradeMonorepo(opts) {
1578
1442
  }
1579
1443
  if (relPath === ".changeset/config.json" && repoName) {
1580
1444
  const changesetJson = await fs.readJson(file.path);
1581
- (0, import_set_value.default)(changesetJson, "changelog.1.repo", repoName);
1445
+ setByPath(changesetJson, "changelog.1.repo", repoName);
1582
1446
  const data = `${JSON.stringify(changesetJson, void 0, 2)}\n`;
1583
1447
  const intent = await evaluateWriteIntent(targetPath, buildWriteIntentOptions(data));
1584
1448
  const action = async () => {
@@ -1646,4 +1510,4 @@ async function upgradeMonorepo(opts) {
1646
1510
  await flushPendingOverwrites(pendingOverwrites);
1647
1511
  }
1648
1512
  //#endregion
1649
- export { defineMonorepoConfig as A, getWorkspacePackages as B, syncSkills as C, templatesDir as D, rootDir as E, generateAgenticTemplate as F, generateAgenticTemplates as I, loadAgenticTasks as L, resolveCommandConfig as M, createTimestampFolderName as N, name as O, defaultAgenticBaseDir as P, logger as R, skillTargets as S, packageDir as T, GitClient as V, getCreateChoices as _, escapeStringRegexp as a, cleanProjects as b, isFileChanged as c, toWorkspaceGitignorePath as d, updateIssueTemplateConfig as f, defaultTemplate as g, createNewProject as h, init as i, loadMonorepoConfig as j, version as k, isGitignoreFile as l, createContext as m, syncNpmMirror as n, isMatch as o, isIgnorableFsError as p, setVscodeBinaryMirror as r, getFileHash as s, upgradeMonorepo as t, toPublishGitignorePath as u, getTemplateMap as v, assetsDir as w, getSkillTargetPaths as x, templateMap as y, getWorkspaceData as z };
1513
+ export { getWorkspaceData as $, toPublishGitignorePath as A, ensureDir as B, resolveCommandConfig as C, getFileHash as D, setByPath as E, generateAgenticTemplate as F, outputJSON as G, exists as H, generateAgenticTemplates as I, readJSON as J, outputJson as K, loadAgenticTasks as L, updateIssueTemplateConfig as M, createTimestampFolderName as N, isFileChanged as O, defaultAgenticBaseDir as P, writeJson as Q, logger as R, loadMonorepoConfig as S, isMatch as T, isIgnorableFsError as U, ensureFile as V, outputFile as W, remove as X, readJson as Y, writeJSON as Z, rootDir as _, createContext as a, version as b, getCreateChoices as c, cleanProjects as d, getWorkspacePackages as et, getSkillTargetPaths as f, packageDir as g, assetsDir as h, init as i, toWorkspaceGitignorePath as j, isGitignoreFile as k, getTemplateMap as l, syncSkills as m, syncNpmMirror as n, createNewProject as o, skillTargets as p, pathExists as q, setVscodeBinaryMirror as r, defaultTemplate as s, upgradeMonorepo as t, GitClient as tt, templateMap as u, templatesDir as v, escapeStringRegexp as w, defineMonorepoConfig as x, name as y, copy as z };