rulesync 34.0.1 → 35.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -583,6 +583,7 @@ const ignoreProcessorToolTargetTuple = [
583
583
  "reasonix",
584
584
  "roo",
585
585
  "tabnine",
586
+ "trae",
586
587
  "devin",
587
588
  "vibe",
588
589
  "warp",
@@ -692,6 +693,7 @@ const commandsProcessorToolTargetTuple = [
692
693
  "rovodev",
693
694
  "tabnine",
694
695
  "takt",
696
+ "trae",
695
697
  "devin",
696
698
  "warp",
697
699
  "zcode",
@@ -1383,20 +1385,22 @@ async function fileExists(filepath) {
1383
1385
  return false;
1384
1386
  }
1385
1387
  }
1386
- async function getFileSize(filepath) {
1388
+ /**
1389
+ * The size of a file and whether it carries any execute bit, read with a single
1390
+ * `stat`. Windows reports no execute bits, so a file there is never seen as
1391
+ * executable.
1392
+ */
1393
+ async function getFileSizeAndExecutableBit(filepath) {
1387
1394
  try {
1388
- return (await stat(filepath)).size;
1395
+ const stats = await stat(filepath);
1396
+ return {
1397
+ size: stats.size,
1398
+ executable: (stats.mode & 73) !== 0
1399
+ };
1389
1400
  } catch (error) {
1390
- throw new Error(`Failed to get file size for "${filepath}": ${formatError(error)}`, { cause: error });
1401
+ throw new Error(`Failed to stat "${filepath}": ${formatError(error)}`, { cause: error });
1391
1402
  }
1392
1403
  }
1393
- /**
1394
- * Whether a file carries any execute bit. Windows reports none, so a file
1395
- * there is never seen as executable.
1396
- */
1397
- async function hasExecutableBit(filepath) {
1398
- return ((await stat(filepath)).mode & 73) !== 0;
1399
- }
1400
1404
  async function isSymlink(filepath) {
1401
1405
  try {
1402
1406
  return (await lstat(filepath)).isSymbolicLink();
@@ -5267,7 +5271,7 @@ const JUNIE_HOOK_EVENTS = [
5267
5271
  * `PreToolUse`, and on the end reason for `SessionEnd`. Only `type: "command"`
5268
5272
  * hooks are supported.
5269
5273
  * @see https://docs.gitlab.com/user/gitlab_duo_cli/customize/
5270
- * @see https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/blob/main/packages/core/hooks/src/schema.ts
5274
+ * @see https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/blob/v9.28.0/packages/core/hooks/src/schema.ts
5271
5275
  */
5272
5276
  const GITLABDUO_HOOK_EVENTS = [
5273
5277
  "sessionStart",
@@ -5621,6 +5625,7 @@ const CORTEXCODE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CA
5621
5625
  *
5622
5626
  * @see https://www.codebuddy.ai/docs/cli/hooks
5623
5627
  * @see https://www.codebuddy.ai/docs/cli/plugins-reference
5628
+ * @see https://www.npmjs.com/package/@tencent-ai/codebuddy-code/v/2.167.0
5624
5629
  */
5625
5630
  const CODEBUDDY_HOOK_EVENTS = [
5626
5631
  "sessionStart",
@@ -23596,6 +23601,157 @@ var TaktCommand = class TaktCommand extends ToolCommand {
23596
23601
  }
23597
23602
  };
23598
23603
  //#endregion
23604
+ //#region src/constants/trae-paths.ts
23605
+ /**
23606
+ * Trae (ByteDance's AI IDE, "TraeCode" in its current docs) keeps project
23607
+ * configuration under `.trae/` and user configuration under `~/.trae/`.
23608
+ *
23609
+ * @see https://docs.trae.ai/ide/rules?_lang=en
23610
+ * @see https://docs.trae.ai/ide/skills?_lang=en
23611
+ * @see https://docs.trae.ai/ide/add-mcp-servers?_lang=en
23612
+ * @see https://docs.trae.ai/ide/slash-commands?_lang=en
23613
+ * @see https://docs.trae.ai/ide/ignore-files?_lang=en
23614
+ */
23615
+ const TRAE_DIR = ".trae";
23616
+ /** Project MCP servers (`mcpServers` object), project scope only. */
23617
+ const TRAE_MCP_FILE_NAME = "mcp.json";
23618
+ /** Skills: `.trae/skills/<name>/SKILL.md` (project) and `~/.trae/skills/` (global). */
23619
+ const TRAE_SKILLS_DIR_PATH = join(TRAE_DIR, "skills");
23620
+ /**
23621
+ * Custom commands: Markdown files under `.trae/commands/` (project, up to three nested
23622
+ * directory levels) and `~/.trae/commands/` (global).
23623
+ */
23624
+ const TRAE_COMMANDS_DIR_PATH = join(TRAE_DIR, "commands");
23625
+ /** Indexing ignore list (gitignore syntax), `.trae/.ignore`, project scope only. */
23626
+ const TRAE_IGNORE_FILE_NAME = ".ignore";
23627
+ //#endregion
23628
+ //#region src/features/commands/trae-command.ts
23629
+ const TraeCommandFrontmatterSchema = z.looseObject({
23630
+ description: z.optional(z.string()),
23631
+ name: z.optional(z.string())
23632
+ });
23633
+ /**
23634
+ * Custom command for Trae.
23635
+ *
23636
+ * Trae reads Markdown command files under `.trae/commands/` (project, up to
23637
+ * three levels of nested directories) and `~/.trae/commands/` (global). The
23638
+ * YAML frontmatter carries `name` and `description`, and the body below the
23639
+ * closing `---` holds the instructions. rulesync writes the rulesync
23640
+ * `description`, a `name` equal to the file name stem (as Trae's editor does),
23641
+ * plus any fields of the `trae` section (which win over the derived ones), and
23642
+ * keeps nested command paths.
23643
+ *
23644
+ * @see https://docs.trae.ai/ide/slash-commands?_lang=en
23645
+ */
23646
+ var TraeCommand = class TraeCommand extends ToolCommand {
23647
+ frontmatter;
23648
+ body;
23649
+ constructor({ frontmatter, body, ...rest }) {
23650
+ if (rest.validate) {
23651
+ const result = TraeCommandFrontmatterSchema.safeParse(frontmatter);
23652
+ if (!result.success) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
23653
+ }
23654
+ super({
23655
+ ...rest,
23656
+ fileContent: stringifyFrontmatter(body, frontmatter)
23657
+ });
23658
+ this.frontmatter = frontmatter;
23659
+ this.body = body;
23660
+ }
23661
+ static getSettablePaths(_options = {}) {
23662
+ return { relativeDirPath: TRAE_COMMANDS_DIR_PATH };
23663
+ }
23664
+ getBody() {
23665
+ return this.body;
23666
+ }
23667
+ getFrontmatter() {
23668
+ return this.frontmatter;
23669
+ }
23670
+ toRulesyncCommand() {
23671
+ const { description, name, ...otherFields } = this.frontmatter;
23672
+ const restFields = name === void 0 || name === basename(this.relativeFilePath, ".md") ? otherFields : {
23673
+ name,
23674
+ ...otherFields
23675
+ };
23676
+ const rulesyncFrontmatter = {
23677
+ targets: ["*"],
23678
+ description,
23679
+ ...Object.keys(restFields).length > 0 && { trae: restFields }
23680
+ };
23681
+ return new RulesyncCommand({
23682
+ outputRoot: ".",
23683
+ frontmatter: rulesyncFrontmatter,
23684
+ body: this.body,
23685
+ relativeDirPath: RulesyncCommand.getSettablePaths().relativeDirPath,
23686
+ relativeFilePath: this.relativeFilePath,
23687
+ fileContent: stringifyFrontmatter(this.body, rulesyncFrontmatter),
23688
+ validate: true
23689
+ });
23690
+ }
23691
+ static fromRulesyncCommand({ outputRoot = process.cwd(), rulesyncCommand, validate = true, global = false }) {
23692
+ const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
23693
+ const traeFrontmatter = {
23694
+ name: basename(rulesyncCommand.getRelativeFilePath(), ".md"),
23695
+ description: rulesyncFrontmatter.description,
23696
+ ...rulesyncFrontmatter.trae
23697
+ };
23698
+ return new TraeCommand({
23699
+ outputRoot,
23700
+ frontmatter: traeFrontmatter,
23701
+ body: rulesyncCommand.getBody(),
23702
+ relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
23703
+ relativeFilePath: rulesyncCommand.getRelativeFilePath(),
23704
+ validate
23705
+ });
23706
+ }
23707
+ validate() {
23708
+ if (!this.frontmatter) return {
23709
+ success: true,
23710
+ error: null
23711
+ };
23712
+ const result = TraeCommandFrontmatterSchema.safeParse(this.frontmatter);
23713
+ if (result.success) return {
23714
+ success: true,
23715
+ error: null
23716
+ };
23717
+ return {
23718
+ success: false,
23719
+ error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
23720
+ };
23721
+ }
23722
+ static isTargetedByRulesyncCommand(rulesyncCommand) {
23723
+ return this.isTargetedByRulesyncCommandDefault({
23724
+ rulesyncCommand,
23725
+ toolTarget: "trae"
23726
+ });
23727
+ }
23728
+ static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
23729
+ const paths = this.getSettablePaths({ global });
23730
+ const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
23731
+ const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
23732
+ const result = TraeCommandFrontmatterSchema.safeParse(frontmatter);
23733
+ if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
23734
+ return new TraeCommand({
23735
+ outputRoot,
23736
+ relativeDirPath: paths.relativeDirPath,
23737
+ relativeFilePath,
23738
+ frontmatter: result.data,
23739
+ body: body.trim(),
23740
+ validate
23741
+ });
23742
+ }
23743
+ static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
23744
+ return new TraeCommand({
23745
+ outputRoot,
23746
+ relativeDirPath,
23747
+ relativeFilePath,
23748
+ frontmatter: { description: "" },
23749
+ body: "",
23750
+ validate: false
23751
+ });
23752
+ }
23753
+ };
23754
+ //#endregion
23599
23755
  //#region src/constants/warp-paths.ts
23600
23756
  const WARP_DIR = ".warp";
23601
23757
  const WARP_SKILLS_DIR_PATH = join(WARP_DIR, "skills");
@@ -24306,6 +24462,16 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
24306
24462
  supportsSubdirectory: false
24307
24463
  }
24308
24464
  }],
24465
+ ["trae", {
24466
+ class: TraeCommand,
24467
+ meta: {
24468
+ extension: "md",
24469
+ supportsProject: true,
24470
+ supportsGlobal: true,
24471
+ isSimulated: false,
24472
+ supportsSubdirectory: true
24473
+ }
24474
+ }],
24309
24475
  ["devin", {
24310
24476
  class: DevinCommand,
24311
24477
  meta: {
@@ -38031,6 +38197,61 @@ var TabnineIgnore = class TabnineIgnore extends ToolIgnore {
38031
38197
  }
38032
38198
  };
38033
38199
  //#endregion
38200
+ //#region src/features/ignore/trae-ignore.ts
38201
+ /**
38202
+ * Trae ignore file implementation.
38203
+ *
38204
+ * Trae reads `.trae/.ignore` (gitignore syntax) as a supplement to
38205
+ * `.gitignore` when it indexes the codebase; ignored files are also left out
38206
+ * of `#Workspace` / `#Folder` context. There is no user-level ignore file, so
38207
+ * only project scope is supported.
38208
+ *
38209
+ * @see https://docs.trae.ai/ide/ignore-files?_lang=en
38210
+ */
38211
+ var TraeIgnore = class TraeIgnore extends ToolIgnore {
38212
+ static getSettablePaths(_params = {}) {
38213
+ return {
38214
+ relativeDirPath: TRAE_DIR,
38215
+ relativeFilePath: TRAE_IGNORE_FILE_NAME
38216
+ };
38217
+ }
38218
+ toRulesyncIgnore() {
38219
+ return this.toRulesyncIgnoreDefault();
38220
+ }
38221
+ static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore, global = false }) {
38222
+ const paths = this.getSettablePaths({ global });
38223
+ return new TraeIgnore({
38224
+ outputRoot,
38225
+ relativeDirPath: paths.relativeDirPath,
38226
+ relativeFilePath: paths.relativeFilePath,
38227
+ fileContent: rulesyncIgnore.getFileContent(),
38228
+ global
38229
+ });
38230
+ }
38231
+ static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
38232
+ const { relativeDirPath, relativeFilePath } = this.getSettablePaths({ global });
38233
+ const fileContent = await readFileContent(join(outputRoot, relativeDirPath, relativeFilePath));
38234
+ return new TraeIgnore({
38235
+ outputRoot,
38236
+ relativeDirPath,
38237
+ relativeFilePath,
38238
+ fileContent,
38239
+ validate,
38240
+ global
38241
+ });
38242
+ }
38243
+ static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
38244
+ return new TraeIgnore({
38245
+ outputRoot,
38246
+ relativeDirPath,
38247
+ relativeFilePath,
38248
+ fileContent: "",
38249
+ validate: false,
38250
+ global
38251
+ });
38252
+ }
38253
+ };
38254
+ //#endregion
38034
38255
  //#region src/features/ignore/vibe-ignore.ts
38035
38256
  var VibeIgnore = class VibeIgnore extends ToolIgnore {
38036
38257
  static getSettablePaths() {
@@ -38259,6 +38480,7 @@ const toolIgnoreFactories = /* @__PURE__ */ new Map([
38259
38480
  ["zoocode", { class: RooIgnore }],
38260
38481
  ["devin", { class: DevinIgnore }],
38261
38482
  ["tabnine", { class: TabnineIgnore }],
38483
+ ["trae", { class: TraeIgnore }],
38262
38484
  ["vibe", { class: VibeIgnore }],
38263
38485
  ["warp", { class: WarpIgnore }],
38264
38486
  ["zed", { class: ZedIgnore }]
@@ -43611,12 +43833,14 @@ function toGitlabduoTimeout({ serverName, server, logger }) {
43611
43833
  /**
43612
43834
  * Read GitLab Duo's `timeoutMs` back into the canonical `timeout`
43613
43835
  * (milliseconds). A server that already carries a `timeout` is left as is, so
43614
- * both keys round-trip and `timeoutMs` keeps winning on the next generate.
43836
+ * both keys round-trip and `timeoutMs` keeps winning on the next generate. A
43837
+ * non-number `timeoutMs` is not copied, since the canonical `timeout` must be a
43838
+ * number; it is kept verbatim as a passthrough key instead.
43615
43839
  */
43616
43840
  function fromGitlabduoTimeout(server) {
43617
43841
  if (typeof server !== "object" || server === null || Array.isArray(server)) return server;
43618
43842
  const { timeoutMs, ...rest } = server;
43619
- if (timeoutMs === void 0 || rest.timeout !== void 0) return server;
43843
+ if (typeof timeoutMs !== "number" || rest.timeout !== void 0) return server;
43620
43844
  return {
43621
43845
  ...rest,
43622
43846
  timeout: timeoutMs
@@ -47089,8 +47313,8 @@ function convertFromPiFormat(mcpServers) {
47089
47313
  * existing file (`autoEnableCodemode`, ...) are preserved. Pi expands `${VAR}`
47090
47314
  * in `env` and `headers` values itself, so those are written unchanged.
47091
47315
  *
47092
- * @see https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md
47093
- * @see https://github.com/earendil-works/pi/blob/main/packages/coding-agent/src/core/mcp-servers.ts
47316
+ * @see https://github.com/earendil-works/pi/blob/v1.1.0/packages/coding-agent/docs/mcp.md
47317
+ * @see https://github.com/earendil-works/pi/blob/v1.1.0/packages/coding-agent/src/core/mcp-servers.ts
47094
47318
  */
47095
47319
  var PiMcp = class PiMcp extends ToolMcp {
47096
47320
  json;
@@ -49204,21 +49428,6 @@ function deriveTransportAllowlist(servers) {
49204
49428
  return allowlist;
49205
49429
  }
49206
49430
  //#endregion
49207
- //#region src/constants/trae-paths.ts
49208
- /**
49209
- * Trae (ByteDance's AI IDE, "TraeCode" in its current docs) keeps project
49210
- * configuration under `.trae/` and user configuration under `~/.trae/`.
49211
- *
49212
- * @see https://docs.trae.ai/ide/rules?_lang=en
49213
- * @see https://docs.trae.ai/ide/skills?_lang=en
49214
- * @see https://docs.trae.ai/ide/add-mcp-servers?_lang=en
49215
- */
49216
- const TRAE_DIR = ".trae";
49217
- /** Project MCP servers (`mcpServers` object), project scope only. */
49218
- const TRAE_MCP_FILE_NAME = "mcp.json";
49219
- /** Skills: `.trae/skills/<name>/SKILL.md` (project) and `~/.trae/skills/` (global). */
49220
- const TRAE_SKILLS_DIR_PATH = join(TRAE_DIR, "skills");
49221
- //#endregion
49222
49431
  //#region src/features/mcp/trae-mcp.ts
49223
49432
  /** A `${...}` reference Trae does not expand: anything but `${workspaceFolder}`. */
49224
49433
  const UNEXPANDED_VARIABLE_REGEX = /\$\{(?!workspaceFolder\})[^}]+\}/;
@@ -51828,6 +52037,11 @@ function parsedGlobsIntersect(left, right, budget) {
51828
52037
  * @see https://antigravity.google/docs/permissions?tab=cli
51829
52038
  */
51830
52039
  const REGEX_PREFIX = "regex:";
52040
+ /**
52041
+ * The Antigravity actions whose target is a command: `command`, and
52042
+ * `unsandboxed`, which takes the same word-by-word prefix or `regex:` target.
52043
+ */
52044
+ const ANTIGRAVITY_COMMAND_ACTIONS = /* @__PURE__ */ new Set(["command", "unsandboxed"]);
51831
52045
  const TRAILING_ANCHOR = /(?<!\\)\$$/;
51832
52046
  const PLAIN_TARGET_GLOB_CHARACTERS = /[*?[{\\]/;
51833
52047
  const REGEX_METACHARACTERS$1 = /[\\^$.|?*+()[\]{}]/;
@@ -52205,8 +52419,8 @@ function toAntigravityCommandLiteralPrefix(pattern) {
52205
52419
  }
52206
52420
  /**
52207
52421
  * Read one regex word back as a glob, or `undefined` when it uses anything a
52208
- * glob cannot say. Antigravity anchors each word anyway, so `^` and `$` are
52209
- * optional. Only escaped characters and `.*` translate; anything else keeps
52422
+ * glob cannot say. Antigravity anchors each word anyway (`^(?:pattern)$`), so
52423
+ * `^` and `$` are optional. Only escaped characters and `.*` translate; anything else keeps
52210
52424
  * the rule a regex.
52211
52425
  */
52212
52426
  function regexWordToGlob(word) {
@@ -52232,8 +52446,10 @@ function regexWordToGlob(word) {
52232
52446
  }
52233
52447
  /** Read a per-word regex back as a glob, or `undefined` when it has no glob spelling. */
52234
52448
  function regexToGlob(source) {
52449
+ const words = splitWords(source);
52450
+ if (words.length === 0) return;
52235
52451
  const globs = [];
52236
- for (const word of splitWords(source)) {
52452
+ for (const word of words) {
52237
52453
  const glob = regexWordToGlob(word);
52238
52454
  if (glob === void 0) return;
52239
52455
  globs.push(glob);
@@ -52258,36 +52474,23 @@ function fromAntigravityCommandTarget(target) {
52258
52474
  return `${target} *`;
52259
52475
  }
52260
52476
  /**
52261
- * Whether a regex word means the same anchored or not: each end is either
52262
- * anchored (`^`, an unescaped `$`) or open-ended (`.*`).
52263
- */
52264
- function isAnchoredWord(word) {
52265
- const startAnchored = word.startsWith("^") || word.startsWith(".*");
52266
- const endAnchored = TRAILING_ANCHOR.test(word) || word.endsWith(".*");
52267
- return startAnchored && endAnchored;
52268
- }
52269
- /**
52270
52477
  * Explain what importing an Antigravity `command` target may lose, or return
52271
52478
  * `undefined` when the import is faithful.
52272
52479
  *
52273
- * - A `regex:` target with a word that is not anchored is imported as a glob
52274
- * that assumes anchoring. If Antigravity matches such a word unanchored,
52275
- * the imported rule is narrower (`regex:rm` also matches `rmdir`).
52276
- * - A plain target holding characters that are special in a glob is most
52277
- * likely the verbatim output of an older rulesync (`command(rm -rf *)`).
52278
- * Antigravity matches it literally, so it imports as a regex that matches a
52279
- * literal `*` word and is inert in the other tools it is exported to.
52480
+ * A plain target holding characters that are special in a glob is most
52481
+ * likely the verbatim output of an older rulesync (`command(rm -rf *)`).
52482
+ * Antigravity matches it literally, so it imports as a regex that matches a
52483
+ * literal `*` word and is inert in the other tools it is exported to.
52484
+ *
52485
+ * A `regex:` word without `^...$` (`regex:rm`) is read as anchored, which is
52486
+ * faithful: Antigravity documents that each token is evaluated as the
52487
+ * anchored regex `^(?:pattern)$`.
52488
+ *
52489
+ * @see https://antigravity.google/docs/permissions
52280
52490
  */
52281
52491
  function describeAntigravityCommandImportLoss(target) {
52282
- if (target.startsWith(REGEX_PREFIX)) {
52283
- const source = target.slice(6);
52284
- if (splitWords(source).some((word) => !isAnchoredWord(word)) && regexToGlob(source) !== void 0) return {
52285
- reason: "it has a regex word without `^...$` anchors and is imported as a glob that assumes Antigravity anchors every word, so the imported rule may be narrower than the original",
52286
- denyConsequence: "The imported deny may block less than it does in Antigravity."
52287
- };
52288
- return;
52289
- }
52290
- if (target !== "*" && PLAIN_TARGET_GLOB_CHARACTERS.test(target)) return {
52492
+ if (target.startsWith(REGEX_PREFIX) || target === "*") return;
52493
+ if (PLAIN_TARGET_GLOB_CHARACTERS.test(target)) return {
52291
52494
  reason: "it holds characters that are special in a glob (`*`, `?`, `[`, `{` or `\\`), which Antigravity matches literally (likely output of an older rulesync), so it is imported as a literal-match regex that no other tool enforces",
52292
52495
  denyConsequence: "This deny is NOT enforced by the other tools it is generated for."
52293
52496
  };
@@ -52319,17 +52522,20 @@ function importAntigravityCommandTarget({ target, entry, decision, logger, toolL
52319
52522
  * every file.
52320
52523
  * - `read_url` takes a domain and covers its subdomains. The URL path is
52321
52524
  * ignored, and `*` covers every domain.
52322
- * - `command` takes literal words or a per-word `regex:`, matched word by
52323
- * word (see `antigravity-command-patterns.ts`).
52525
+ * - `execute_url` takes a domain, like `read_url`.
52526
+ * - `command` and `unsandboxed` take literal words or a per-word `regex:`,
52527
+ * matched word by word (see `antigravity-command-patterns.ts`).
52324
52528
  *
52325
52529
  * A glob copied verbatim (`read_file(**\/*.env)`) is a literal path that
52326
52530
  * matches nothing, so a deny written that way blocks nothing. A pattern with
52327
- * no Antigravity spelling is skipped with a warning instead, except a command
52328
- * deny with leading literal words, which is widened to them.
52531
+ * no Antigravity spelling is skipped with a warning instead, except a deny
52532
+ * with a literal lead (the first words of a command, the leading directories
52533
+ * of a path), which is widened to it.
52329
52534
  *
52330
52535
  * @see https://antigravity.google/docs/permissions?tab=cli
52331
52536
  */
52332
52537
  const PATH_ACTIONS = /* @__PURE__ */ new Set(["read_file", "write_file"]);
52538
+ const URL_ACTIONS = /* @__PURE__ */ new Set(["read_url", "execute_url"]);
52333
52539
  const MATCH_ALL_PATH_GLOBS = /* @__PURE__ */ new Set([
52334
52540
  "*",
52335
52541
  "**",
@@ -52341,7 +52547,8 @@ const HOSTNAME = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/;
52341
52547
  const DENY_HINTS = {
52342
52548
  read_file: "deny a directory or file path instead",
52343
52549
  write_file: "deny a directory or file path instead",
52344
- command: "deny the first words of the command instead"
52550
+ command: "deny the first words of the command instead",
52551
+ unsandboxed: "deny the first words of the command instead"
52345
52552
  };
52346
52553
  function hasGlob(pattern) {
52347
52554
  return BRACE_ALTERNATIVES.test(pattern) || parseGlobPattern(pattern).steps.some((step) => step.kind !== "literal");
@@ -52392,37 +52599,88 @@ function toUrlTarget(pattern) {
52392
52599
  };
52393
52600
  }
52394
52601
  function toTarget(action, pattern) {
52395
- if (action === "command") return toAntigravityCommandTarget(pattern);
52602
+ if (ANTIGRAVITY_COMMAND_ACTIONS.has(action)) return toAntigravityCommandTarget(pattern);
52396
52603
  if (PATH_ACTIONS.has(action)) return toPathTarget(pattern);
52397
- if (action === "read_url") return toUrlTarget(pattern);
52604
+ if (URL_ACTIONS.has(action)) return toUrlTarget(pattern);
52398
52605
  return { target: pattern };
52399
52606
  }
52400
52607
  /**
52608
+ * The leading directories of a path glob (`src` for `src/*.ts`), or
52609
+ * `undefined` when it has none. A directory target covers everything inside
52610
+ * it, so it matches at least as much as the glob. The filesystem root alone
52611
+ * (`/*`) is not a lead: a deny of it would block every file. Neither is a lead
52612
+ * with `..` in it.
52613
+ */
52614
+ function toPathLiteralPrefix(pattern) {
52615
+ const path = pattern.startsWith("./") ? pattern.slice(2) : pattern;
52616
+ const prefix = [];
52617
+ for (const segment of path.split("/").slice(0, -1)) {
52618
+ if (hasGlob(segment) || segment.includes("{") || segment.includes("}")) break;
52619
+ prefix.push(segment);
52620
+ }
52621
+ if (prefix.includes("..") || prefix.every((segment) => segment === "" || segment === ".")) return;
52622
+ return prefix.join("/");
52623
+ }
52624
+ /** The widened target of a deny that has no exact Antigravity spelling. */
52625
+ function toWidenedDenyTarget(action, pattern) {
52626
+ if (ANTIGRAVITY_COMMAND_ACTIONS.has(action)) return toAntigravityCommandLiteralPrefix(pattern);
52627
+ if (PATH_ACTIONS.has(action)) return toPathLiteralPrefix(pattern);
52628
+ }
52629
+ /**
52630
+ * Warn about a path target that is a home or variable reference. Antigravity
52631
+ * documents absolute and workspace-relative paths only, so such a reference
52632
+ * may be matched literally and never apply. The entry is still written, since
52633
+ * dropping a deny would lose it where Antigravity does expand the reference.
52634
+ */
52635
+ function warnHomeOrVariablePath({ action, target, rule, decision, logger, toolLabel }) {
52636
+ if (!PATH_ACTIONS.has(action) || !HOME_OR_VARIABLE_PATH.test(target)) return;
52637
+ const consequence = decision === "deny" ? "this deny may block nothing" : decision === "ask" ? `${toolLabel} may fall back to its default, so it may run without a prompt when ${toolLabel} is set to always proceed` : `${toolLabel} may fall back to its default`;
52638
+ logger.warn(`${toolLabel} permissions: ${rule}: \`~\` and environment variables may not be expanded in Antigravity path targets, so ${action}(${target}) may match nothing and ${consequence}; use an absolute path instead.`);
52639
+ }
52640
+ /**
52401
52641
  * Build the entry for one canonical rule, or return `undefined` when
52402
- * Antigravity cannot express it. A command deny is widened to its leading
52403
- * literal words rather than skipped: Antigravity applies deny over ask and
52404
- * allow, so an overlapping allow that is translated (`git push *`) cannot let
52405
- * through what the deny (`git push * --force`) was meant to block. A skipped
52406
- * deny is warned about loudly, because nothing enforces it.
52642
+ * Antigravity cannot express it. A deny is widened to its literal lead rather
52643
+ * than skipped (`git push * --force` → `command(git push)`, `src/*.ts` →
52644
+ * `read_file(src)`): Antigravity applies deny over ask and allow, so an
52645
+ * overlapping allow that is translated (`git push *`) cannot let through what
52646
+ * the deny was meant to block. A skipped deny is warned about loudly, because
52647
+ * nothing enforces it, and a widened one is warned about too, because it
52648
+ * blocks more than it says.
52407
52649
  */
52408
52650
  function buildAntigravityPermissionEntry({ action, category, pattern, decision, logger, toolLabel }) {
52409
52651
  const result = pattern === "*" ? { target: "*" } : toTarget(action, pattern);
52410
52652
  const rule = `${category}: { "${pattern}": "${decision}" }`;
52411
52653
  if ("skipReason" in result) {
52412
- const prefix = action === "command" && decision === "deny" ? toAntigravityCommandLiteralPrefix(pattern) : void 0;
52654
+ const prefix = decision === "deny" ? toWidenedDenyTarget(action, pattern) : void 0;
52413
52655
  if (prefix !== void 0) {
52414
- logger.warn(`${toolLabel} permissions: widening ${rule} to ${action}(${prefix}). ${result.skipReason}. The deny now blocks every command that starts with \`${prefix}\`, overriding any allow or ask for them.`);
52656
+ const scope = PATH_ACTIONS.has(action) ? `every path under \`${prefix}\`` : `every command that starts with \`${prefix}\``;
52657
+ logger.warn(`${toolLabel} permissions: widening ${rule} to ${action}(${prefix}). ${result.skipReason}. The deny now blocks ${scope}, overriding any allow or ask for them.`);
52658
+ warnHomeOrVariablePath({
52659
+ action,
52660
+ target: prefix,
52661
+ rule,
52662
+ decision,
52663
+ logger,
52664
+ toolLabel
52665
+ });
52415
52666
  return `${action}(${prefix})`;
52416
52667
  }
52417
52668
  const consequence = decision === "deny" ? `This deny is NOT enforced in ${toolLabel}; ${DENY_HINTS[action] ?? "write it in a form Antigravity can match"}` : decision === "ask" ? `${toolLabel} falls back to its default for it, so it runs without a prompt when ${toolLabel} is set to always proceed` : `${toolLabel} falls back to its default for it`;
52418
52669
  logger.warn(`${toolLabel} permissions: skipping ${rule}. ${result.skipReason}. ${consequence}.`);
52419
52670
  return;
52420
52671
  }
52421
- if (result.note !== void 0 && decision !== "deny") logger.warn(`${toolLabel} permissions: ${rule}: ${result.note}.`);
52422
- if (PATH_ACTIONS.has(action) && HOME_OR_VARIABLE_PATH.test(result.target)) {
52423
- const consequence = decision === "deny" ? "this deny may block nothing" : `${toolLabel} may fall back to its default`;
52424
- logger.warn(`${toolLabel} permissions: ${rule}: \`~\` and environment variables may not be expanded in Antigravity path targets, so ${action}(${result.target}) may match nothing and ${consequence}; use an absolute path instead.`);
52672
+ if (result.note !== void 0 && (decision !== "deny" || URL_ACTIONS.has(action))) {
52673
+ const consequence = decision === "deny" ? ", so the deny also overrides any allow or ask there" : "";
52674
+ logger.warn(`${toolLabel} permissions: ${rule}: ${result.note}${consequence}.`);
52425
52675
  }
52676
+ warnHomeOrVariablePath({
52677
+ action,
52678
+ target: result.target,
52679
+ rule,
52680
+ decision,
52681
+ logger,
52682
+ toolLabel
52683
+ });
52426
52684
  return result.target === "*" ? action : `${action}(${result.target})`;
52427
52685
  }
52428
52686
  //#endregion
@@ -52756,7 +53014,8 @@ function pickDocumentedValue({ key, value, documented }) {
52756
53014
  * Deliberate mapping from rulesync canonical permission categories to the
52757
53015
  * Antigravity CLI Fine-Grained Permissions Engine action vocabulary
52758
53016
  * (`read_file`, `write_file`, `read_url`, `command`, `mcp`, plus `execute_url` /
52759
- * `unsandboxed` which have no canonical equivalent and pass through). `edit` and
53017
+ * `unsandboxed` which have no canonical equivalent and keep their names; their
53018
+ * targets are translated like `read_url` / `command` ones). `edit` and
52760
53019
  * `write` both map to `write_file`, and `webfetch` / `websearch` both map to
52761
53020
  * `read_url`; on import those collapse to the canonical `write` / `webfetch`
52762
53021
  * form (a documented, lossy normalization). This shares the action vocabulary of
@@ -53003,7 +53262,7 @@ function convertAntigravityCliToRulesyncPermissions(params) {
53003
53262
  for (const entry of entries) {
53004
53263
  const { toolName, pattern: target } = parsePermissionEntry$1(entry);
53005
53264
  const canonical = toCanonicalToolName$9(toolName);
53006
- const pattern = toolName === "command" ? importAntigravityCommandTarget({
53265
+ const pattern = ANTIGRAVITY_COMMAND_ACTIONS.has(toolName) ? importAntigravityCommandTarget({
53007
53266
  target,
53008
53267
  entry,
53009
53268
  decision: action,
@@ -53025,7 +53284,8 @@ function convertAntigravityCliToRulesyncPermissions(params) {
53025
53284
  * Deliberate mapping from rulesync canonical permission categories to the
53026
53285
  * Antigravity IDE action vocabulary (`read_file`, `write_file`, `read_url`,
53027
53286
  * `command`, `mcp`, plus `execute_url` / `unsandboxed` which have no canonical
53028
- * equivalent and pass through). `edit` and `write` both map to `write_file`, and
53287
+ * equivalent and keep their names; their targets are translated like
53288
+ * `read_url` / `command` ones). `edit` and `write` both map to `write_file`, and
53029
53289
  * `webfetch` / `websearch` both map to `read_url`; on import those collapse to
53030
53290
  * the canonical `write` / `webfetch` form (a documented, lossy normalization).
53031
53291
  */
@@ -53227,7 +53487,7 @@ function convertAntigravityIdeToRulesyncPermissions(params) {
53227
53487
  for (const entry of entries) {
53228
53488
  const { action: ideAction, pattern: target } = parsePermissionEntry(entry);
53229
53489
  const canonical = toCanonicalCategory$2(ideAction);
53230
- const pattern = ideAction === "command" ? importAntigravityCommandTarget({
53490
+ const pattern = ANTIGRAVITY_COMMAND_ACTIONS.has(ideAction) ? importAntigravityCommandTarget({
53231
53491
  target,
53232
53492
  entry,
53233
53493
  decision: action,
@@ -72504,6 +72764,335 @@ var PermissionsProcessor = class extends FeatureProcessor {
72504
72764
  }
72505
72765
  };
72506
72766
  //#endregion
72767
+ //#region src/types/tool-display.ts
72768
+ const TOOL_DISPLAY = [
72769
+ {
72770
+ key: "agentsmd",
72771
+ label: "AGENTS.md",
72772
+ group: "standard"
72773
+ },
72774
+ {
72775
+ key: "agentsskills",
72776
+ label: "AgentsSkills",
72777
+ group: "standard"
72778
+ },
72779
+ {
72780
+ key: "amp",
72781
+ label: "Amp",
72782
+ group: "ai"
72783
+ },
72784
+ {
72785
+ key: "bob",
72786
+ label: "IBM Bob",
72787
+ group: "ai"
72788
+ },
72789
+ {
72790
+ key: "claudecode",
72791
+ label: "Claude Code",
72792
+ group: "ai"
72793
+ },
72794
+ {
72795
+ key: "claudecode-plugin",
72796
+ label: "Claude Code plugin",
72797
+ group: "ai"
72798
+ },
72799
+ {
72800
+ key: "codebuddy",
72801
+ label: "CodeBuddy Code",
72802
+ group: "ai"
72803
+ },
72804
+ {
72805
+ key: "codewhale",
72806
+ label: "Codewhale",
72807
+ group: "ai"
72808
+ },
72809
+ {
72810
+ key: "codexcli",
72811
+ label: "Codex CLI",
72812
+ group: "ai"
72813
+ },
72814
+ {
72815
+ key: "commandcode",
72816
+ label: "Command Code",
72817
+ group: "ai"
72818
+ },
72819
+ {
72820
+ key: "copilot",
72821
+ label: "GitHub Copilot",
72822
+ group: "ai"
72823
+ },
72824
+ {
72825
+ key: "copilotcli",
72826
+ label: "GitHub Copilot CLI",
72827
+ group: "ai"
72828
+ },
72829
+ {
72830
+ key: "crush",
72831
+ label: "Crush",
72832
+ group: "ai"
72833
+ },
72834
+ {
72835
+ key: "goose",
72836
+ label: "Goose",
72837
+ group: "ai"
72838
+ },
72839
+ {
72840
+ key: "hermesagent",
72841
+ label: "Hermes Agent",
72842
+ group: "ai"
72843
+ },
72844
+ {
72845
+ key: "grokcli",
72846
+ label: "Grok CLI",
72847
+ group: "ai"
72848
+ },
72849
+ {
72850
+ key: "cursor",
72851
+ label: "Cursor",
72852
+ group: "ai"
72853
+ },
72854
+ {
72855
+ key: "deepagents",
72856
+ label: "deepagents-cli",
72857
+ group: "ai"
72858
+ },
72859
+ {
72860
+ key: "factorydroid",
72861
+ label: "Factory Droid",
72862
+ group: "ai"
72863
+ },
72864
+ {
72865
+ key: "opencode",
72866
+ label: "OpenCode",
72867
+ group: "ai"
72868
+ },
72869
+ {
72870
+ key: "openclaw",
72871
+ label: "OpenClaw",
72872
+ group: "ai"
72873
+ },
72874
+ {
72875
+ key: "mimocode",
72876
+ label: "MiMo Code",
72877
+ group: "ai"
72878
+ },
72879
+ {
72880
+ key: "gitlabduo",
72881
+ label: "GitLab Duo CLI",
72882
+ group: "ai"
72883
+ },
72884
+ {
72885
+ key: "cline",
72886
+ label: "Cline",
72887
+ group: "ai"
72888
+ },
72889
+ {
72890
+ key: "kilo",
72891
+ label: "Kilo Code",
72892
+ group: "ai"
72893
+ },
72894
+ {
72895
+ key: "kimi-code",
72896
+ label: "Kimi Code",
72897
+ group: "ai"
72898
+ },
72899
+ {
72900
+ key: "kimi-code-plugin",
72901
+ label: "Kimi Code plugin",
72902
+ group: "ai"
72903
+ },
72904
+ {
72905
+ key: "roo",
72906
+ label: "Roo Code ⚠️",
72907
+ group: "ai"
72908
+ },
72909
+ {
72910
+ key: "zoocode",
72911
+ label: "Zoo Code",
72912
+ group: "ai"
72913
+ },
72914
+ {
72915
+ key: "rovodev",
72916
+ label: "Rovodev (Atlassian) ⚠️",
72917
+ group: "ai"
72918
+ },
72919
+ {
72920
+ key: "takt",
72921
+ label: "Takt",
72922
+ group: "ai"
72923
+ },
72924
+ {
72925
+ key: "trae",
72926
+ label: "Trae",
72927
+ group: "ai"
72928
+ },
72929
+ {
72930
+ key: "tabnine",
72931
+ label: "Tabnine CLI ⚠️",
72932
+ group: "ai"
72933
+ },
72934
+ {
72935
+ key: "continue",
72936
+ label: "Continue ⚠️",
72937
+ group: "ai"
72938
+ },
72939
+ {
72940
+ key: "cortexcode",
72941
+ label: "Snowflake Cortex Code",
72942
+ group: "ai"
72943
+ },
72944
+ {
72945
+ key: "vibe",
72946
+ label: "Vibe Code",
72947
+ group: "ai"
72948
+ },
72949
+ {
72950
+ key: "vibe-plugin",
72951
+ label: "Vibe Code plugin",
72952
+ group: "ai"
72953
+ },
72954
+ {
72955
+ key: "qoder",
72956
+ label: "Qoder",
72957
+ group: "ai"
72958
+ },
72959
+ {
72960
+ key: "qwencode",
72961
+ label: "Qwen Code",
72962
+ group: "ai"
72963
+ },
72964
+ {
72965
+ key: "musecode",
72966
+ label: "Meta Muse Code",
72967
+ group: "ai"
72968
+ },
72969
+ {
72970
+ key: "reasonix",
72971
+ label: "Reasonix",
72972
+ group: "ai"
72973
+ },
72974
+ {
72975
+ key: "codebuff",
72976
+ label: "Codebuff (Freebuff)",
72977
+ group: "ai"
72978
+ },
72979
+ {
72980
+ key: "kiro",
72981
+ label: "Kiro ⚠️",
72982
+ group: "ai"
72983
+ },
72984
+ {
72985
+ key: "kiro-cli",
72986
+ label: "Kiro CLI",
72987
+ group: "ai"
72988
+ },
72989
+ {
72990
+ key: "kiro-ide",
72991
+ label: "Kiro IDE",
72992
+ group: "ai"
72993
+ },
72994
+ {
72995
+ key: "lettacode",
72996
+ label: "Letta Code",
72997
+ group: "ai"
72998
+ },
72999
+ {
73000
+ key: "antigravity-ide",
73001
+ label: "Google Antigravity IDE",
73002
+ group: "ai"
73003
+ },
73004
+ {
73005
+ key: "antigravity-cli",
73006
+ label: "Google Antigravity CLI",
73007
+ group: "ai"
73008
+ },
73009
+ {
73010
+ key: "antigravity-plugin",
73011
+ label: "Google Antigravity plugin",
73012
+ group: "ai"
73013
+ },
73014
+ {
73015
+ key: "aiassistant",
73016
+ label: "JetBrains AI Assistant",
73017
+ group: "ai"
73018
+ },
73019
+ {
73020
+ key: "junie",
73021
+ label: "JetBrains Junie",
73022
+ group: "ai"
73023
+ },
73024
+ {
73025
+ key: "augmentcode",
73026
+ label: "AugmentCode",
73027
+ group: "ai"
73028
+ },
73029
+ {
73030
+ key: "augmentcode-plugin",
73031
+ label: "AugmentCode plugin",
73032
+ group: "ai"
73033
+ },
73034
+ {
73035
+ key: "devin",
73036
+ label: "Devin Desktop",
73037
+ group: "ai"
73038
+ },
73039
+ {
73040
+ key: "devin-plugin",
73041
+ label: "Devin plugin",
73042
+ group: "ai"
73043
+ },
73044
+ {
73045
+ key: "warp",
73046
+ label: "Warp",
73047
+ group: "ai"
73048
+ },
73049
+ {
73050
+ key: "warpcli",
73051
+ label: "Warp Agent CLI",
73052
+ group: "ai"
73053
+ },
73054
+ {
73055
+ key: "replit",
73056
+ label: "Replit",
73057
+ group: "ai"
73058
+ },
73059
+ {
73060
+ key: "pi",
73061
+ label: "Pi Coding Agent",
73062
+ group: "ai"
73063
+ },
73064
+ {
73065
+ key: "omp",
73066
+ label: "oh-my-pi",
73067
+ group: "ai"
73068
+ },
73069
+ {
73070
+ key: "zed",
73071
+ label: "Zed",
73072
+ group: "ai"
73073
+ },
73074
+ {
73075
+ key: "zcode",
73076
+ label: "ZCode (Z.ai)",
73077
+ group: "ai"
73078
+ },
73079
+ {
73080
+ key: "zcode-plugin",
73081
+ label: "ZCode plugin",
73082
+ group: "ai"
73083
+ },
73084
+ {
73085
+ key: "pool",
73086
+ label: "Pool (Poolside)",
73087
+ group: "ai"
73088
+ },
73089
+ {
73090
+ key: "dsh",
73091
+ label: "DeepSeek Harness",
73092
+ group: "ai"
73093
+ }
73094
+ ];
73095
+ //#endregion
72507
73096
  //#region src/features/skills/simulated-skill.ts
72508
73097
  const SimulatedSkillFrontmatterSchema = z.looseObject({
72509
73098
  name: z.string(),
@@ -84849,7 +85438,7 @@ var DeepagentsSubagent = class DeepagentsSubagent extends ToolSubagent {
84849
85438
  //#endregion
84850
85439
  //#region src/features/subagents/devin-subagent.ts
84851
85440
  const DevinSubagentFrontmatterSchema = z.looseObject({
84852
- name: z.string(),
85441
+ name: z.optional(z.string()),
84853
85442
  description: z.optional(z.string()),
84854
85443
  model: z.optional(z.string()),
84855
85444
  "allowed-tools": z.optional(z.array(z.string())),
@@ -84902,7 +85491,7 @@ var DevinSubagent = class extends ToolSubagent {
84902
85491
  outputRoot: ".",
84903
85492
  frontmatter: {
84904
85493
  targets: ["*"],
84905
- name,
85494
+ name: name ?? this.getSubagentName(),
84906
85495
  description,
84907
85496
  ...Object.keys(devinSection).length > 0 && { devin: devinSection }
84908
85497
  },
@@ -84976,7 +85565,8 @@ var DevinSubagent = class extends ToolSubagent {
84976
85565
  const paths = this.getSettablePaths({ global });
84977
85566
  const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
84978
85567
  const fileContent = await readFileContent(filePath);
84979
- const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
85568
+ const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(fileContent, filePath);
85569
+ if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${filePath}`);
84980
85570
  const result = DevinSubagentFrontmatterSchema.safeParse(frontmatter);
84981
85571
  if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
84982
85572
  return new this({
@@ -98624,6 +99214,7 @@ var RulesProcessor = class extends FeatureProcessor {
98624
99214
  warnForOutputStyleRuleOptions({ rules, factory }) {
98625
99215
  const toolTarget = this.toolTarget;
98626
99216
  if (toolTarget !== "factorydroid" && toolTarget !== "qoder") return;
99217
+ const toolLabel = TOOL_DISPLAY.find((entry) => entry.key === toolTarget)?.label ?? toolTarget;
98627
99218
  for (const rule of rules) {
98628
99219
  const frontmatter = rule.getFrontmatter();
98629
99220
  const section = frontmatter[toolTarget];
@@ -98631,7 +99222,7 @@ var RulesProcessor = class extends FeatureProcessor {
98631
99222
  const { channel, name } = section;
98632
99223
  const fileName = stripControlCharacters(rule.getRelativeFilePath());
98633
99224
  const targets = frontmatter.targets ?? ["*"];
98634
- if (channel === "output-style" && targets.some((target) => target !== toolTarget)) this.logger.warn(`${fileName} sets ${toolTarget}.channel: output-style but also targets other tools, which receive it as an ordinary rule. Set \`targets: ["${toolTarget}"]\` to keep the output style to ${toolTarget === "qoder" ? "Qoder" : "Factory Droid"}.`);
99225
+ if (channel === "output-style" && targets.some((target) => target !== toolTarget)) this.logger.warn(`${fileName} sets ${toolTarget}.channel: output-style but also targets other tools, which receive it as an ordinary rule. Set \`targets: ["${toolTarget}"]\` to keep the output style to ${toolLabel}.`);
98635
99226
  if (channel !== "output-style" && name !== void 0) this.logger.warn(`${fileName} sets ${toolTarget}.name, which is read only with ${toolTarget}.channel: output-style; ignoring it.`);
98636
99227
  }
98637
99228
  }
@@ -102377,6 +102968,6 @@ async function importChecksCore(params) {
102377
102968
  return writtenCount;
102378
102969
  }
102379
102970
  //#endregion
102380
- export { RulesyncHooks as $, removeDirectoryStrict as $t, groupSpellingsByCaseFoldedIdentity as A, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as An, applyFileMode as At, QWENCODE_LOCAL_RULE_FILE_NAME as B, ALL_FEATURES as Bn, getFileSize as Bt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as C, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as Cn, fallbackLogger as Ct, FACTORYDROID_DIR as D, RULESYNC_MCP_RELATIVE_FILE_PATH as Dn, withWarnOnceScope as Dt, ChecksProcessor as E, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as En, resetRunWarningState as Et, CLAUDECODE_LOCAL_RULE_FILE_NAME as F, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Fn, createTempDirectory as Ft, RulesyncSubagentFrontmatterSchema as G, hasDeceptiveHiddenCharacters as Gn, isSymlink as Gt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as H, DEPRECATED_FEATURE_REPLACEMENTS as Hn, hasExecutableBit as Ht, CLAUDECODE_MEMORIES_DIR_NAME as I, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as In, directoryExists as It, RulesyncRule as J, stripControlCharacters as Jn, listSubdirectoryNames as Jt, RulesyncSkill as K, hasEnclosingMarkOutsideKeycap as Kn, listDirectoryEntryNames as Kt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as L, RULESYNC_USER_CONFIG_DIR_NAME as Ln, ensureDir as Lt, CODEXCLI_DIR as M, RULESYNC_RELATIVE_DIR_PATH as Mn, assertTreeContainsNoSymlinks as Mt, CLAUDECODE_AGENT_MEMORY_LOCAL_DIR_NAME as N, RULESYNC_RULES_RELATIVE_DIR_PATH as Nn, assertWritablePathInsideRoot as Nt, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as O, RULESYNC_MCP_SCHEMA_URL as On, CLIError as Ot, CLAUDECODE_DIR as P, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Pn, checkPathTraversal as Pt, RulesyncIgnore as Q, removeDirectory as Qt, CLAUDECODE_SKILLS_DIR_PATH as R, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as Rn, fileExists as Rt, COMMANDCODE_DIR as S, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as Sn, WarningCollectingLogger as St, CODEBUDDY_LOCAL_RULE_FILE_NAME as T, RULESYNC_IGNORE_RELATIVE_FILE_PATH as Tn, withFallbackLoggerTarget as Tt, getLocalSkillDirNames as U, formatError as Un, isFileNotFoundError as Ut, AUGMENTCODE_DIR as V, ALL_FEATURES_WITH_WILDCARD as Vn, getHomeDirectory as Vt, RulesyncSubagent as W, truncateText as Wn, isFileSystemError as Wt, RulesyncPermissions as X, stripHiddenCharacters as Xn, readFileContent as Xt, RulesyncRuleFrontmatterSchema as Y, stripControlCharactersKeepingLineFeeds as Yn, pathEscapesRoot as Yt, RulesyncMcp as Z, readFileContentOrNull as Zt, LETTACODE_DIR as _, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as _n, SourceEntrySchema as _t, getProcessorRegistryEntry as a, runWithDirectoryRollback as an, RulesyncCheck as at, CommandsProcessor as b, RULESYNC_CONFIG_RELATIVE_FILE_PATH as bn, ConsoleLogger as bt, RulesProcessor as c, writeFileBuffer as cn, loadYaml as ct, ELLIPSIS_WIDTH as d, ALL_TOOL_TARGETS_WITH_WILDCARD as dn, ConfigResolver as dt, removeFile as en, getRulesyncSourceCandidates as et, displayWidthOf as f, PACKAGING_TOOL_TARGETS as fn, mergeInputRootConfigs as ft, HooksProcessor as g, MAX_FILE_SIZE as gn, GITIGNORE_DESTINATION_KEY as gt, IgnoreProcessor as h, FEATURE_SOURCE_TREE_ENTRIES as hn, ConfigFileSchema as ht, inspectInputRoots as i, resolvedPathEscapesRoot as in, RulesyncCommandFrontmatterSchema as it, CODEXCLI_BASH_RULES_FILE_NAME as j, RULESYNC_PERMISSIONS_SCHEMA_URL as jn, assertDirectoryIfExists as jt, caseFoldIdentity as k, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as kn, ErrorCodes as kt, SubagentsProcessor as l, writeFileContent as ln, SHARED_USER_MANAGED_CONFIG_PATHS as lt, McpProcessor as m, CURATED_RULES_FEATURE_SUBDIR as mn, CONFLICTING_TARGET_PAIRS as mt, formatSourceLoadFailure as n, removeTempDirectory as nn, parseJsonc as nt, convertFromTool as o, splitPathSegments as on, RulesyncCheckFrontmatterSchema as ot, shortenToWidth as p, ToolTargetSchema as pn, resolveEffectiveInputRoots as pt, RulesyncSkillFrontmatterSchema as q, quoteForLog as qn, listFilePathsRecursively as qt, generate as r, resolvePath as rn, RulesyncCommand as rt, isPackagingToolTarget as s, toPosixPath as sn, stringifyFrontmatter as st, importFromTool as t, removeFileStrict as tn, resolveRulesyncSourceWritePath as tt, SkillsProcessor as u, ALL_TOOL_TARGETS as un, SKILL_FILE_NAME as ut, LETTACODE_SETTINGS_LOCAL_FILE_NAME as v, RULESYNC_CHECKS_RELATIVE_DIR_PATH as vn, assertTargetsFeaturesExclusive as vt, CODEBUDDY_DIR as w, RULESYNC_HOOKS_RELATIVE_FILE_PATH as wn, warnOnConflictingFlags as wt, REASONIX_LOCAL_RULE_FILE_NAME as x, RULESYNC_CONFIG_SCHEMA_URL as xn, JsonLogger as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as yn, findControlCharacter as yt, QWENCODE_DIR as z, parseCommaSeparatedList as zn, findFilesByGlobs as zt };
102971
+ export { RulesyncHooks as $, removeDirectoryStrict as $t, groupSpellingsByCaseFoldedIdentity as A, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as An, applyFileMode as At, QWENCODE_LOCAL_RULE_FILE_NAME as B, ALL_FEATURES as Bn, getFileSizeAndExecutableBit as Bt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as C, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as Cn, fallbackLogger as Ct, FACTORYDROID_DIR as D, RULESYNC_MCP_RELATIVE_FILE_PATH as Dn, withWarnOnceScope as Dt, ChecksProcessor as E, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as En, resetRunWarningState as Et, CLAUDECODE_LOCAL_RULE_FILE_NAME as F, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Fn, createTempDirectory as Ft, RulesyncSubagentFrontmatterSchema as G, hasDeceptiveHiddenCharacters as Gn, listDirectoryEntryNames as Gt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as H, DEPRECATED_FEATURE_REPLACEMENTS as Hn, isFileNotFoundError as Ht, CLAUDECODE_MEMORIES_DIR_NAME as I, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as In, directoryExists as It, RulesyncRule as J, stripControlCharacters as Jn, pathEscapesRoot as Jt, RulesyncSkill as K, hasEnclosingMarkOutsideKeycap as Kn, listFilePathsRecursively as Kt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as L, RULESYNC_USER_CONFIG_DIR_NAME as Ln, ensureDir as Lt, CODEXCLI_DIR as M, RULESYNC_RELATIVE_DIR_PATH as Mn, assertTreeContainsNoSymlinks as Mt, CLAUDECODE_AGENT_MEMORY_LOCAL_DIR_NAME as N, RULESYNC_RULES_RELATIVE_DIR_PATH as Nn, assertWritablePathInsideRoot as Nt, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as O, RULESYNC_MCP_SCHEMA_URL as On, CLIError as Ot, CLAUDECODE_DIR as P, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Pn, checkPathTraversal as Pt, RulesyncIgnore as Q, removeDirectory as Qt, CLAUDECODE_SKILLS_DIR_PATH as R, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as Rn, fileExists as Rt, COMMANDCODE_DIR as S, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as Sn, WarningCollectingLogger as St, CODEBUDDY_LOCAL_RULE_FILE_NAME as T, RULESYNC_IGNORE_RELATIVE_FILE_PATH as Tn, withFallbackLoggerTarget as Tt, getLocalSkillDirNames as U, formatError as Un, isFileSystemError as Ut, AUGMENTCODE_DIR as V, ALL_FEATURES_WITH_WILDCARD as Vn, getHomeDirectory as Vt, RulesyncSubagent as W, truncateText as Wn, isSymlink as Wt, RulesyncPermissions as X, stripHiddenCharacters as Xn, readFileContent as Xt, RulesyncRuleFrontmatterSchema as Y, stripControlCharactersKeepingLineFeeds as Yn, posixRelativePathEscapesRoot as Yt, RulesyncMcp as Z, readFileContentOrNull as Zt, LETTACODE_DIR as _, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as _n, SourceEntrySchema as _t, getProcessorRegistryEntry as a, runWithDirectoryRollback as an, RulesyncCheck as at, CommandsProcessor as b, RULESYNC_CONFIG_RELATIVE_FILE_PATH as bn, ConsoleLogger as bt, RulesProcessor as c, writeFileBuffer as cn, loadYaml as ct, ELLIPSIS_WIDTH as d, ALL_TOOL_TARGETS_WITH_WILDCARD as dn, ConfigResolver as dt, removeFile as en, getRulesyncSourceCandidates as et, displayWidthOf as f, PACKAGING_TOOL_TARGETS as fn, mergeInputRootConfigs as ft, HooksProcessor as g, MAX_FILE_SIZE as gn, GITIGNORE_DESTINATION_KEY as gt, IgnoreProcessor as h, FEATURE_SOURCE_TREE_ENTRIES as hn, ConfigFileSchema as ht, inspectInputRoots as i, resolvedRelativePath as in, RulesyncCommandFrontmatterSchema as it, CODEXCLI_BASH_RULES_FILE_NAME as j, RULESYNC_PERMISSIONS_SCHEMA_URL as jn, assertDirectoryIfExists as jt, caseFoldIdentity as k, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as kn, ErrorCodes as kt, SubagentsProcessor as l, writeFileContent as ln, SHARED_USER_MANAGED_CONFIG_PATHS as lt, McpProcessor as m, CURATED_RULES_FEATURE_SUBDIR as mn, CONFLICTING_TARGET_PAIRS as mt, formatSourceLoadFailure as n, removeTempDirectory as nn, parseJsonc as nt, convertFromTool as o, splitPathSegments as on, RulesyncCheckFrontmatterSchema as ot, shortenToWidth as p, ToolTargetSchema as pn, resolveEffectiveInputRoots as pt, RulesyncSkillFrontmatterSchema as q, quoteForLog as qn, listSubdirectoryNames as qt, generate as r, resolvePath as rn, RulesyncCommand as rt, isPackagingToolTarget as s, toPosixPath as sn, stringifyFrontmatter as st, importFromTool as t, removeFileStrict as tn, resolveRulesyncSourceWritePath as tt, SkillsProcessor as u, ALL_TOOL_TARGETS as un, SKILL_FILE_NAME as ut, LETTACODE_SETTINGS_LOCAL_FILE_NAME as v, RULESYNC_CHECKS_RELATIVE_DIR_PATH as vn, assertTargetsFeaturesExclusive as vt, CODEBUDDY_DIR as w, RULESYNC_HOOKS_RELATIVE_FILE_PATH as wn, warnOnConflictingFlags as wt, REASONIX_LOCAL_RULE_FILE_NAME as x, RULESYNC_CONFIG_SCHEMA_URL as xn, JsonLogger as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as yn, findControlCharacter as yt, QWENCODE_DIR as z, parseCommaSeparatedList as zn, findFilesByGlobs as zt };
102381
102972
 
102382
- //# sourceMappingURL=import-DFwX4TTE.js.map
102973
+ //# sourceMappingURL=import-BbF_R5Qx.js.map