rulesync 34.0.0 → 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.
- package/README.md +1 -1
- package/dist/cli/index.cjs +51 -17
- package/dist/cli/index.js +51 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-DFwX4TTE.js → import-BbF_R5Qx.js} +677 -86
- package/dist/{import-DFwX4TTE.js.map → import-BbF_R5Qx.js.map} +1 -1
- package/dist/{import-Bx0zNGBx.cjs → import-D11JFP84.cjs} +702 -111
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -457,36 +457,36 @@ const isFeatureValueEnabled = (value) => {
|
|
|
457
457
|
const parseCommaSeparatedList = (value) => value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
458
458
|
//#endregion
|
|
459
459
|
//#region src/constants/rulesync-paths.ts
|
|
460
|
-
const { join: join$
|
|
460
|
+
const { join: join$420 } = node_path.posix;
|
|
461
461
|
const RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
|
|
462
462
|
const RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH = "rulesync.local.jsonc";
|
|
463
463
|
const RULESYNC_USER_CONFIG_DIR_NAME = "rulesync";
|
|
464
464
|
const RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME = ".config";
|
|
465
465
|
const RULESYNC_RELATIVE_DIR_PATH = ".rulesync";
|
|
466
466
|
const RULES_FEATURE_SUBDIR = "rules";
|
|
467
|
-
const CURATED_RULES_FEATURE_SUBDIR = join$
|
|
467
|
+
const CURATED_RULES_FEATURE_SUBDIR = join$420(RULES_FEATURE_SUBDIR, ".curated");
|
|
468
468
|
const COMMANDS_FEATURE_SUBDIR = "commands";
|
|
469
469
|
const SUBAGENTS_FEATURE_SUBDIR = "subagents";
|
|
470
470
|
const CHECKS_FEATURE_SUBDIR = "checks";
|
|
471
471
|
const SKILLS_FEATURE_SUBDIR = "skills";
|
|
472
|
-
const CURATED_SKILLS_FEATURE_SUBDIR = join$
|
|
473
|
-
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$
|
|
474
|
-
const RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH = join$
|
|
475
|
-
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$
|
|
476
|
-
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$
|
|
477
|
-
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$
|
|
478
|
-
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$
|
|
479
|
-
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$
|
|
480
|
-
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$
|
|
481
|
-
join$
|
|
482
|
-
const RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH = join$
|
|
483
|
-
const RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH = join$
|
|
472
|
+
const CURATED_SKILLS_FEATURE_SUBDIR = join$420(SKILLS_FEATURE_SUBDIR, ".curated");
|
|
473
|
+
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, RULES_FEATURE_SUBDIR);
|
|
474
|
+
const RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, CURATED_RULES_FEATURE_SUBDIR);
|
|
475
|
+
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, COMMANDS_FEATURE_SUBDIR);
|
|
476
|
+
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, SUBAGENTS_FEATURE_SUBDIR);
|
|
477
|
+
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, CHECKS_FEATURE_SUBDIR);
|
|
478
|
+
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, "mcp.jsonc");
|
|
479
|
+
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, "hooks.jsonc");
|
|
480
|
+
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, "permissions.jsonc");
|
|
481
|
+
join$420(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
|
|
482
|
+
const RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, "hooks.json");
|
|
483
|
+
const RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, "permissions.json");
|
|
484
484
|
const RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
|
|
485
|
-
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$
|
|
485
|
+
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
|
|
486
486
|
const RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
|
|
487
487
|
const RULESYNC_OVERVIEW_FILE_NAME = "overview.md";
|
|
488
|
-
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$
|
|
489
|
-
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$
|
|
488
|
+
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, SKILLS_FEATURE_SUBDIR);
|
|
489
|
+
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$420(RULESYNC_RELATIVE_DIR_PATH, CURATED_SKILLS_FEATURE_SUBDIR);
|
|
490
490
|
const RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync.lock";
|
|
491
491
|
const RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync-npm.lock.json";
|
|
492
492
|
const RULESYNC_MCP_FILE_NAME = "mcp.jsonc";
|
|
@@ -605,6 +605,7 @@ const ignoreProcessorToolTargetTuple = [
|
|
|
605
605
|
"reasonix",
|
|
606
606
|
"roo",
|
|
607
607
|
"tabnine",
|
|
608
|
+
"trae",
|
|
608
609
|
"devin",
|
|
609
610
|
"vibe",
|
|
610
611
|
"warp",
|
|
@@ -714,6 +715,7 @@ const commandsProcessorToolTargetTuple = [
|
|
|
714
715
|
"rovodev",
|
|
715
716
|
"tabnine",
|
|
716
717
|
"takt",
|
|
718
|
+
"trae",
|
|
717
719
|
"devin",
|
|
718
720
|
"warp",
|
|
719
721
|
"zcode",
|
|
@@ -1405,20 +1407,22 @@ async function fileExists(filepath) {
|
|
|
1405
1407
|
return false;
|
|
1406
1408
|
}
|
|
1407
1409
|
}
|
|
1408
|
-
|
|
1410
|
+
/**
|
|
1411
|
+
* The size of a file and whether it carries any execute bit, read with a single
|
|
1412
|
+
* `stat`. Windows reports no execute bits, so a file there is never seen as
|
|
1413
|
+
* executable.
|
|
1414
|
+
*/
|
|
1415
|
+
async function getFileSizeAndExecutableBit(filepath) {
|
|
1409
1416
|
try {
|
|
1410
|
-
|
|
1417
|
+
const stats = await (0, node_fs_promises.stat)(filepath);
|
|
1418
|
+
return {
|
|
1419
|
+
size: stats.size,
|
|
1420
|
+
executable: (stats.mode & 73) !== 0
|
|
1421
|
+
};
|
|
1411
1422
|
} catch (error) {
|
|
1412
|
-
throw new Error(`Failed to
|
|
1423
|
+
throw new Error(`Failed to stat "${filepath}": ${formatError(error)}`, { cause: error });
|
|
1413
1424
|
}
|
|
1414
1425
|
}
|
|
1415
|
-
/**
|
|
1416
|
-
* Whether a file carries any execute bit. Windows reports none, so a file
|
|
1417
|
-
* there is never seen as executable.
|
|
1418
|
-
*/
|
|
1419
|
-
async function hasExecutableBit(filepath) {
|
|
1420
|
-
return ((await (0, node_fs_promises.stat)(filepath)).mode & 73) !== 0;
|
|
1421
|
-
}
|
|
1422
1426
|
async function isSymlink(filepath) {
|
|
1423
1427
|
try {
|
|
1424
1428
|
return (await (0, node_fs_promises.lstat)(filepath)).isSymbolicLink();
|
|
@@ -5289,7 +5293,7 @@ const JUNIE_HOOK_EVENTS = [
|
|
|
5289
5293
|
* `PreToolUse`, and on the end reason for `SessionEnd`. Only `type: "command"`
|
|
5290
5294
|
* hooks are supported.
|
|
5291
5295
|
* @see https://docs.gitlab.com/user/gitlab_duo_cli/customize/
|
|
5292
|
-
* @see https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/blob/
|
|
5296
|
+
* @see https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/blob/v9.28.0/packages/core/hooks/src/schema.ts
|
|
5293
5297
|
*/
|
|
5294
5298
|
const GITLABDUO_HOOK_EVENTS = [
|
|
5295
5299
|
"sessionStart",
|
|
@@ -5643,6 +5647,7 @@ const CORTEXCODE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CA
|
|
|
5643
5647
|
*
|
|
5644
5648
|
* @see https://www.codebuddy.ai/docs/cli/hooks
|
|
5645
5649
|
* @see https://www.codebuddy.ai/docs/cli/plugins-reference
|
|
5650
|
+
* @see https://www.npmjs.com/package/@tencent-ai/codebuddy-code/v/2.167.0
|
|
5646
5651
|
*/
|
|
5647
5652
|
const CODEBUDDY_HOOK_EVENTS = [
|
|
5648
5653
|
"sessionStart",
|
|
@@ -23618,6 +23623,157 @@ var TaktCommand = class TaktCommand extends ToolCommand {
|
|
|
23618
23623
|
}
|
|
23619
23624
|
};
|
|
23620
23625
|
//#endregion
|
|
23626
|
+
//#region src/constants/trae-paths.ts
|
|
23627
|
+
/**
|
|
23628
|
+
* Trae (ByteDance's AI IDE, "TraeCode" in its current docs) keeps project
|
|
23629
|
+
* configuration under `.trae/` and user configuration under `~/.trae/`.
|
|
23630
|
+
*
|
|
23631
|
+
* @see https://docs.trae.ai/ide/rules?_lang=en
|
|
23632
|
+
* @see https://docs.trae.ai/ide/skills?_lang=en
|
|
23633
|
+
* @see https://docs.trae.ai/ide/add-mcp-servers?_lang=en
|
|
23634
|
+
* @see https://docs.trae.ai/ide/slash-commands?_lang=en
|
|
23635
|
+
* @see https://docs.trae.ai/ide/ignore-files?_lang=en
|
|
23636
|
+
*/
|
|
23637
|
+
const TRAE_DIR = ".trae";
|
|
23638
|
+
/** Project MCP servers (`mcpServers` object), project scope only. */
|
|
23639
|
+
const TRAE_MCP_FILE_NAME = "mcp.json";
|
|
23640
|
+
/** Skills: `.trae/skills/<name>/SKILL.md` (project) and `~/.trae/skills/` (global). */
|
|
23641
|
+
const TRAE_SKILLS_DIR_PATH = (0, node_path.join)(TRAE_DIR, "skills");
|
|
23642
|
+
/**
|
|
23643
|
+
* Custom commands: Markdown files under `.trae/commands/` (project, up to three nested
|
|
23644
|
+
* directory levels) and `~/.trae/commands/` (global).
|
|
23645
|
+
*/
|
|
23646
|
+
const TRAE_COMMANDS_DIR_PATH = (0, node_path.join)(TRAE_DIR, "commands");
|
|
23647
|
+
/** Indexing ignore list (gitignore syntax), `.trae/.ignore`, project scope only. */
|
|
23648
|
+
const TRAE_IGNORE_FILE_NAME = ".ignore";
|
|
23649
|
+
//#endregion
|
|
23650
|
+
//#region src/features/commands/trae-command.ts
|
|
23651
|
+
const TraeCommandFrontmatterSchema = zod_mini.z.looseObject({
|
|
23652
|
+
description: zod_mini.z.optional(zod_mini.z.string()),
|
|
23653
|
+
name: zod_mini.z.optional(zod_mini.z.string())
|
|
23654
|
+
});
|
|
23655
|
+
/**
|
|
23656
|
+
* Custom command for Trae.
|
|
23657
|
+
*
|
|
23658
|
+
* Trae reads Markdown command files under `.trae/commands/` (project, up to
|
|
23659
|
+
* three levels of nested directories) and `~/.trae/commands/` (global). The
|
|
23660
|
+
* YAML frontmatter carries `name` and `description`, and the body below the
|
|
23661
|
+
* closing `---` holds the instructions. rulesync writes the rulesync
|
|
23662
|
+
* `description`, a `name` equal to the file name stem (as Trae's editor does),
|
|
23663
|
+
* plus any fields of the `trae` section (which win over the derived ones), and
|
|
23664
|
+
* keeps nested command paths.
|
|
23665
|
+
*
|
|
23666
|
+
* @see https://docs.trae.ai/ide/slash-commands?_lang=en
|
|
23667
|
+
*/
|
|
23668
|
+
var TraeCommand = class TraeCommand extends ToolCommand {
|
|
23669
|
+
frontmatter;
|
|
23670
|
+
body;
|
|
23671
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
23672
|
+
if (rest.validate) {
|
|
23673
|
+
const result = TraeCommandFrontmatterSchema.safeParse(frontmatter);
|
|
23674
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
23675
|
+
}
|
|
23676
|
+
super({
|
|
23677
|
+
...rest,
|
|
23678
|
+
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
23679
|
+
});
|
|
23680
|
+
this.frontmatter = frontmatter;
|
|
23681
|
+
this.body = body;
|
|
23682
|
+
}
|
|
23683
|
+
static getSettablePaths(_options = {}) {
|
|
23684
|
+
return { relativeDirPath: TRAE_COMMANDS_DIR_PATH };
|
|
23685
|
+
}
|
|
23686
|
+
getBody() {
|
|
23687
|
+
return this.body;
|
|
23688
|
+
}
|
|
23689
|
+
getFrontmatter() {
|
|
23690
|
+
return this.frontmatter;
|
|
23691
|
+
}
|
|
23692
|
+
toRulesyncCommand() {
|
|
23693
|
+
const { description, name, ...otherFields } = this.frontmatter;
|
|
23694
|
+
const restFields = name === void 0 || name === (0, node_path.basename)(this.relativeFilePath, ".md") ? otherFields : {
|
|
23695
|
+
name,
|
|
23696
|
+
...otherFields
|
|
23697
|
+
};
|
|
23698
|
+
const rulesyncFrontmatter = {
|
|
23699
|
+
targets: ["*"],
|
|
23700
|
+
description,
|
|
23701
|
+
...Object.keys(restFields).length > 0 && { trae: restFields }
|
|
23702
|
+
};
|
|
23703
|
+
return new RulesyncCommand({
|
|
23704
|
+
outputRoot: ".",
|
|
23705
|
+
frontmatter: rulesyncFrontmatter,
|
|
23706
|
+
body: this.body,
|
|
23707
|
+
relativeDirPath: RulesyncCommand.getSettablePaths().relativeDirPath,
|
|
23708
|
+
relativeFilePath: this.relativeFilePath,
|
|
23709
|
+
fileContent: stringifyFrontmatter(this.body, rulesyncFrontmatter),
|
|
23710
|
+
validate: true
|
|
23711
|
+
});
|
|
23712
|
+
}
|
|
23713
|
+
static fromRulesyncCommand({ outputRoot = process.cwd(), rulesyncCommand, validate = true, global = false }) {
|
|
23714
|
+
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
23715
|
+
const traeFrontmatter = {
|
|
23716
|
+
name: (0, node_path.basename)(rulesyncCommand.getRelativeFilePath(), ".md"),
|
|
23717
|
+
description: rulesyncFrontmatter.description,
|
|
23718
|
+
...rulesyncFrontmatter.trae
|
|
23719
|
+
};
|
|
23720
|
+
return new TraeCommand({
|
|
23721
|
+
outputRoot,
|
|
23722
|
+
frontmatter: traeFrontmatter,
|
|
23723
|
+
body: rulesyncCommand.getBody(),
|
|
23724
|
+
relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
|
|
23725
|
+
relativeFilePath: rulesyncCommand.getRelativeFilePath(),
|
|
23726
|
+
validate
|
|
23727
|
+
});
|
|
23728
|
+
}
|
|
23729
|
+
validate() {
|
|
23730
|
+
if (!this.frontmatter) return {
|
|
23731
|
+
success: true,
|
|
23732
|
+
error: null
|
|
23733
|
+
};
|
|
23734
|
+
const result = TraeCommandFrontmatterSchema.safeParse(this.frontmatter);
|
|
23735
|
+
if (result.success) return {
|
|
23736
|
+
success: true,
|
|
23737
|
+
error: null
|
|
23738
|
+
};
|
|
23739
|
+
return {
|
|
23740
|
+
success: false,
|
|
23741
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
23742
|
+
};
|
|
23743
|
+
}
|
|
23744
|
+
static isTargetedByRulesyncCommand(rulesyncCommand) {
|
|
23745
|
+
return this.isTargetedByRulesyncCommandDefault({
|
|
23746
|
+
rulesyncCommand,
|
|
23747
|
+
toolTarget: "trae"
|
|
23748
|
+
});
|
|
23749
|
+
}
|
|
23750
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
23751
|
+
const paths = this.getSettablePaths({ global });
|
|
23752
|
+
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
23753
|
+
const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
23754
|
+
const result = TraeCommandFrontmatterSchema.safeParse(frontmatter);
|
|
23755
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
23756
|
+
return new TraeCommand({
|
|
23757
|
+
outputRoot,
|
|
23758
|
+
relativeDirPath: paths.relativeDirPath,
|
|
23759
|
+
relativeFilePath,
|
|
23760
|
+
frontmatter: result.data,
|
|
23761
|
+
body: body.trim(),
|
|
23762
|
+
validate
|
|
23763
|
+
});
|
|
23764
|
+
}
|
|
23765
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
23766
|
+
return new TraeCommand({
|
|
23767
|
+
outputRoot,
|
|
23768
|
+
relativeDirPath,
|
|
23769
|
+
relativeFilePath,
|
|
23770
|
+
frontmatter: { description: "" },
|
|
23771
|
+
body: "",
|
|
23772
|
+
validate: false
|
|
23773
|
+
});
|
|
23774
|
+
}
|
|
23775
|
+
};
|
|
23776
|
+
//#endregion
|
|
23621
23777
|
//#region src/constants/warp-paths.ts
|
|
23622
23778
|
const WARP_DIR = ".warp";
|
|
23623
23779
|
const WARP_SKILLS_DIR_PATH = (0, node_path.join)(WARP_DIR, "skills");
|
|
@@ -24328,6 +24484,16 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
24328
24484
|
supportsSubdirectory: false
|
|
24329
24485
|
}
|
|
24330
24486
|
}],
|
|
24487
|
+
["trae", {
|
|
24488
|
+
class: TraeCommand,
|
|
24489
|
+
meta: {
|
|
24490
|
+
extension: "md",
|
|
24491
|
+
supportsProject: true,
|
|
24492
|
+
supportsGlobal: true,
|
|
24493
|
+
isSimulated: false,
|
|
24494
|
+
supportsSubdirectory: true
|
|
24495
|
+
}
|
|
24496
|
+
}],
|
|
24331
24497
|
["devin", {
|
|
24332
24498
|
class: DevinCommand,
|
|
24333
24499
|
meta: {
|
|
@@ -38053,6 +38219,61 @@ var TabnineIgnore = class TabnineIgnore extends ToolIgnore {
|
|
|
38053
38219
|
}
|
|
38054
38220
|
};
|
|
38055
38221
|
//#endregion
|
|
38222
|
+
//#region src/features/ignore/trae-ignore.ts
|
|
38223
|
+
/**
|
|
38224
|
+
* Trae ignore file implementation.
|
|
38225
|
+
*
|
|
38226
|
+
* Trae reads `.trae/.ignore` (gitignore syntax) as a supplement to
|
|
38227
|
+
* `.gitignore` when it indexes the codebase; ignored files are also left out
|
|
38228
|
+
* of `#Workspace` / `#Folder` context. There is no user-level ignore file, so
|
|
38229
|
+
* only project scope is supported.
|
|
38230
|
+
*
|
|
38231
|
+
* @see https://docs.trae.ai/ide/ignore-files?_lang=en
|
|
38232
|
+
*/
|
|
38233
|
+
var TraeIgnore = class TraeIgnore extends ToolIgnore {
|
|
38234
|
+
static getSettablePaths(_params = {}) {
|
|
38235
|
+
return {
|
|
38236
|
+
relativeDirPath: TRAE_DIR,
|
|
38237
|
+
relativeFilePath: TRAE_IGNORE_FILE_NAME
|
|
38238
|
+
};
|
|
38239
|
+
}
|
|
38240
|
+
toRulesyncIgnore() {
|
|
38241
|
+
return this.toRulesyncIgnoreDefault();
|
|
38242
|
+
}
|
|
38243
|
+
static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore, global = false }) {
|
|
38244
|
+
const paths = this.getSettablePaths({ global });
|
|
38245
|
+
return new TraeIgnore({
|
|
38246
|
+
outputRoot,
|
|
38247
|
+
relativeDirPath: paths.relativeDirPath,
|
|
38248
|
+
relativeFilePath: paths.relativeFilePath,
|
|
38249
|
+
fileContent: rulesyncIgnore.getFileContent(),
|
|
38250
|
+
global
|
|
38251
|
+
});
|
|
38252
|
+
}
|
|
38253
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
38254
|
+
const { relativeDirPath, relativeFilePath } = this.getSettablePaths({ global });
|
|
38255
|
+
const fileContent = await readFileContent((0, node_path.join)(outputRoot, relativeDirPath, relativeFilePath));
|
|
38256
|
+
return new TraeIgnore({
|
|
38257
|
+
outputRoot,
|
|
38258
|
+
relativeDirPath,
|
|
38259
|
+
relativeFilePath,
|
|
38260
|
+
fileContent,
|
|
38261
|
+
validate,
|
|
38262
|
+
global
|
|
38263
|
+
});
|
|
38264
|
+
}
|
|
38265
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
38266
|
+
return new TraeIgnore({
|
|
38267
|
+
outputRoot,
|
|
38268
|
+
relativeDirPath,
|
|
38269
|
+
relativeFilePath,
|
|
38270
|
+
fileContent: "",
|
|
38271
|
+
validate: false,
|
|
38272
|
+
global
|
|
38273
|
+
});
|
|
38274
|
+
}
|
|
38275
|
+
};
|
|
38276
|
+
//#endregion
|
|
38056
38277
|
//#region src/features/ignore/vibe-ignore.ts
|
|
38057
38278
|
var VibeIgnore = class VibeIgnore extends ToolIgnore {
|
|
38058
38279
|
static getSettablePaths() {
|
|
@@ -38281,6 +38502,7 @@ const toolIgnoreFactories = /* @__PURE__ */ new Map([
|
|
|
38281
38502
|
["zoocode", { class: RooIgnore }],
|
|
38282
38503
|
["devin", { class: DevinIgnore }],
|
|
38283
38504
|
["tabnine", { class: TabnineIgnore }],
|
|
38505
|
+
["trae", { class: TraeIgnore }],
|
|
38284
38506
|
["vibe", { class: VibeIgnore }],
|
|
38285
38507
|
["warp", { class: WarpIgnore }],
|
|
38286
38508
|
["zed", { class: ZedIgnore }]
|
|
@@ -43633,12 +43855,14 @@ function toGitlabduoTimeout({ serverName, server, logger }) {
|
|
|
43633
43855
|
/**
|
|
43634
43856
|
* Read GitLab Duo's `timeoutMs` back into the canonical `timeout`
|
|
43635
43857
|
* (milliseconds). A server that already carries a `timeout` is left as is, so
|
|
43636
|
-
* both keys round-trip and `timeoutMs` keeps winning on the next generate.
|
|
43858
|
+
* both keys round-trip and `timeoutMs` keeps winning on the next generate. A
|
|
43859
|
+
* non-number `timeoutMs` is not copied, since the canonical `timeout` must be a
|
|
43860
|
+
* number; it is kept verbatim as a passthrough key instead.
|
|
43637
43861
|
*/
|
|
43638
43862
|
function fromGitlabduoTimeout(server) {
|
|
43639
43863
|
if (typeof server !== "object" || server === null || Array.isArray(server)) return server;
|
|
43640
43864
|
const { timeoutMs, ...rest } = server;
|
|
43641
|
-
if (timeoutMs
|
|
43865
|
+
if (typeof timeoutMs !== "number" || rest.timeout !== void 0) return server;
|
|
43642
43866
|
return {
|
|
43643
43867
|
...rest,
|
|
43644
43868
|
timeout: timeoutMs
|
|
@@ -47111,8 +47335,8 @@ function convertFromPiFormat(mcpServers) {
|
|
|
47111
47335
|
* existing file (`autoEnableCodemode`, ...) are preserved. Pi expands `${VAR}`
|
|
47112
47336
|
* in `env` and `headers` values itself, so those are written unchanged.
|
|
47113
47337
|
*
|
|
47114
|
-
* @see https://github.com/earendil-works/pi/blob/
|
|
47115
|
-
* @see https://github.com/earendil-works/pi/blob/
|
|
47338
|
+
* @see https://github.com/earendil-works/pi/blob/v1.1.0/packages/coding-agent/docs/mcp.md
|
|
47339
|
+
* @see https://github.com/earendil-works/pi/blob/v1.1.0/packages/coding-agent/src/core/mcp-servers.ts
|
|
47116
47340
|
*/
|
|
47117
47341
|
var PiMcp = class PiMcp extends ToolMcp {
|
|
47118
47342
|
json;
|
|
@@ -49226,21 +49450,6 @@ function deriveTransportAllowlist(servers) {
|
|
|
49226
49450
|
return allowlist;
|
|
49227
49451
|
}
|
|
49228
49452
|
//#endregion
|
|
49229
|
-
//#region src/constants/trae-paths.ts
|
|
49230
|
-
/**
|
|
49231
|
-
* Trae (ByteDance's AI IDE, "TraeCode" in its current docs) keeps project
|
|
49232
|
-
* configuration under `.trae/` and user configuration under `~/.trae/`.
|
|
49233
|
-
*
|
|
49234
|
-
* @see https://docs.trae.ai/ide/rules?_lang=en
|
|
49235
|
-
* @see https://docs.trae.ai/ide/skills?_lang=en
|
|
49236
|
-
* @see https://docs.trae.ai/ide/add-mcp-servers?_lang=en
|
|
49237
|
-
*/
|
|
49238
|
-
const TRAE_DIR = ".trae";
|
|
49239
|
-
/** Project MCP servers (`mcpServers` object), project scope only. */
|
|
49240
|
-
const TRAE_MCP_FILE_NAME = "mcp.json";
|
|
49241
|
-
/** Skills: `.trae/skills/<name>/SKILL.md` (project) and `~/.trae/skills/` (global). */
|
|
49242
|
-
const TRAE_SKILLS_DIR_PATH = (0, node_path.join)(TRAE_DIR, "skills");
|
|
49243
|
-
//#endregion
|
|
49244
49453
|
//#region src/features/mcp/trae-mcp.ts
|
|
49245
49454
|
/** A `${...}` reference Trae does not expand: anything but `${workspaceFolder}`. */
|
|
49246
49455
|
const UNEXPANDED_VARIABLE_REGEX = /\$\{(?!workspaceFolder\})[^}]+\}/;
|
|
@@ -51850,6 +52059,11 @@ function parsedGlobsIntersect(left, right, budget) {
|
|
|
51850
52059
|
* @see https://antigravity.google/docs/permissions?tab=cli
|
|
51851
52060
|
*/
|
|
51852
52061
|
const REGEX_PREFIX = "regex:";
|
|
52062
|
+
/**
|
|
52063
|
+
* The Antigravity actions whose target is a command: `command`, and
|
|
52064
|
+
* `unsandboxed`, which takes the same word-by-word prefix or `regex:` target.
|
|
52065
|
+
*/
|
|
52066
|
+
const ANTIGRAVITY_COMMAND_ACTIONS = /* @__PURE__ */ new Set(["command", "unsandboxed"]);
|
|
51853
52067
|
const TRAILING_ANCHOR = /(?<!\\)\$$/;
|
|
51854
52068
|
const PLAIN_TARGET_GLOB_CHARACTERS = /[*?[{\\]/;
|
|
51855
52069
|
const REGEX_METACHARACTERS$1 = /[\\^$.|?*+()[\]{}]/;
|
|
@@ -52227,8 +52441,8 @@ function toAntigravityCommandLiteralPrefix(pattern) {
|
|
|
52227
52441
|
}
|
|
52228
52442
|
/**
|
|
52229
52443
|
* Read one regex word back as a glob, or `undefined` when it uses anything a
|
|
52230
|
-
* glob cannot say. Antigravity anchors each word anyway, so
|
|
52231
|
-
* optional. Only escaped characters and `.*` translate; anything else keeps
|
|
52444
|
+
* glob cannot say. Antigravity anchors each word anyway (`^(?:pattern)$`), so
|
|
52445
|
+
* `^` and `$` are optional. Only escaped characters and `.*` translate; anything else keeps
|
|
52232
52446
|
* the rule a regex.
|
|
52233
52447
|
*/
|
|
52234
52448
|
function regexWordToGlob(word) {
|
|
@@ -52254,8 +52468,10 @@ function regexWordToGlob(word) {
|
|
|
52254
52468
|
}
|
|
52255
52469
|
/** Read a per-word regex back as a glob, or `undefined` when it has no glob spelling. */
|
|
52256
52470
|
function regexToGlob(source) {
|
|
52471
|
+
const words = splitWords(source);
|
|
52472
|
+
if (words.length === 0) return;
|
|
52257
52473
|
const globs = [];
|
|
52258
|
-
for (const word of
|
|
52474
|
+
for (const word of words) {
|
|
52259
52475
|
const glob = regexWordToGlob(word);
|
|
52260
52476
|
if (glob === void 0) return;
|
|
52261
52477
|
globs.push(glob);
|
|
@@ -52280,36 +52496,23 @@ function fromAntigravityCommandTarget(target) {
|
|
|
52280
52496
|
return `${target} *`;
|
|
52281
52497
|
}
|
|
52282
52498
|
/**
|
|
52283
|
-
* Whether a regex word means the same anchored or not: each end is either
|
|
52284
|
-
* anchored (`^`, an unescaped `$`) or open-ended (`.*`).
|
|
52285
|
-
*/
|
|
52286
|
-
function isAnchoredWord(word) {
|
|
52287
|
-
const startAnchored = word.startsWith("^") || word.startsWith(".*");
|
|
52288
|
-
const endAnchored = TRAILING_ANCHOR.test(word) || word.endsWith(".*");
|
|
52289
|
-
return startAnchored && endAnchored;
|
|
52290
|
-
}
|
|
52291
|
-
/**
|
|
52292
52499
|
* Explain what importing an Antigravity `command` target may lose, or return
|
|
52293
52500
|
* `undefined` when the import is faithful.
|
|
52294
52501
|
*
|
|
52295
|
-
*
|
|
52296
|
-
*
|
|
52297
|
-
*
|
|
52298
|
-
*
|
|
52299
|
-
*
|
|
52300
|
-
*
|
|
52301
|
-
*
|
|
52502
|
+
* A plain target holding characters that are special in a glob is most
|
|
52503
|
+
* likely the verbatim output of an older rulesync (`command(rm -rf *)`).
|
|
52504
|
+
* Antigravity matches it literally, so it imports as a regex that matches a
|
|
52505
|
+
* literal `*` word and is inert in the other tools it is exported to.
|
|
52506
|
+
*
|
|
52507
|
+
* A `regex:` word without `^...$` (`regex:rm`) is read as anchored, which is
|
|
52508
|
+
* faithful: Antigravity documents that each token is evaluated as the
|
|
52509
|
+
* anchored regex `^(?:pattern)$`.
|
|
52510
|
+
*
|
|
52511
|
+
* @see https://antigravity.google/docs/permissions
|
|
52302
52512
|
*/
|
|
52303
52513
|
function describeAntigravityCommandImportLoss(target) {
|
|
52304
|
-
if (target.startsWith(REGEX_PREFIX))
|
|
52305
|
-
|
|
52306
|
-
if (splitWords(source).some((word) => !isAnchoredWord(word)) && regexToGlob(source) !== void 0) return {
|
|
52307
|
-
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",
|
|
52308
|
-
denyConsequence: "The imported deny may block less than it does in Antigravity."
|
|
52309
|
-
};
|
|
52310
|
-
return;
|
|
52311
|
-
}
|
|
52312
|
-
if (target !== "*" && PLAIN_TARGET_GLOB_CHARACTERS.test(target)) return {
|
|
52514
|
+
if (target.startsWith(REGEX_PREFIX) || target === "*") return;
|
|
52515
|
+
if (PLAIN_TARGET_GLOB_CHARACTERS.test(target)) return {
|
|
52313
52516
|
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",
|
|
52314
52517
|
denyConsequence: "This deny is NOT enforced by the other tools it is generated for."
|
|
52315
52518
|
};
|
|
@@ -52341,17 +52544,20 @@ function importAntigravityCommandTarget({ target, entry, decision, logger, toolL
|
|
|
52341
52544
|
* every file.
|
|
52342
52545
|
* - `read_url` takes a domain and covers its subdomains. The URL path is
|
|
52343
52546
|
* ignored, and `*` covers every domain.
|
|
52344
|
-
* - `
|
|
52345
|
-
*
|
|
52547
|
+
* - `execute_url` takes a domain, like `read_url`.
|
|
52548
|
+
* - `command` and `unsandboxed` take literal words or a per-word `regex:`,
|
|
52549
|
+
* matched word by word (see `antigravity-command-patterns.ts`).
|
|
52346
52550
|
*
|
|
52347
52551
|
* A glob copied verbatim (`read_file(**\/*.env)`) is a literal path that
|
|
52348
52552
|
* matches nothing, so a deny written that way blocks nothing. A pattern with
|
|
52349
|
-
* no Antigravity spelling is skipped with a warning instead, except a
|
|
52350
|
-
*
|
|
52553
|
+
* no Antigravity spelling is skipped with a warning instead, except a deny
|
|
52554
|
+
* with a literal lead (the first words of a command, the leading directories
|
|
52555
|
+
* of a path), which is widened to it.
|
|
52351
52556
|
*
|
|
52352
52557
|
* @see https://antigravity.google/docs/permissions?tab=cli
|
|
52353
52558
|
*/
|
|
52354
52559
|
const PATH_ACTIONS = /* @__PURE__ */ new Set(["read_file", "write_file"]);
|
|
52560
|
+
const URL_ACTIONS = /* @__PURE__ */ new Set(["read_url", "execute_url"]);
|
|
52355
52561
|
const MATCH_ALL_PATH_GLOBS = /* @__PURE__ */ new Set([
|
|
52356
52562
|
"*",
|
|
52357
52563
|
"**",
|
|
@@ -52363,7 +52569,8 @@ const HOSTNAME = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/;
|
|
|
52363
52569
|
const DENY_HINTS = {
|
|
52364
52570
|
read_file: "deny a directory or file path instead",
|
|
52365
52571
|
write_file: "deny a directory or file path instead",
|
|
52366
|
-
command: "deny the first words of the command instead"
|
|
52572
|
+
command: "deny the first words of the command instead",
|
|
52573
|
+
unsandboxed: "deny the first words of the command instead"
|
|
52367
52574
|
};
|
|
52368
52575
|
function hasGlob(pattern) {
|
|
52369
52576
|
return BRACE_ALTERNATIVES.test(pattern) || parseGlobPattern(pattern).steps.some((step) => step.kind !== "literal");
|
|
@@ -52414,37 +52621,88 @@ function toUrlTarget(pattern) {
|
|
|
52414
52621
|
};
|
|
52415
52622
|
}
|
|
52416
52623
|
function toTarget(action, pattern) {
|
|
52417
|
-
if (action
|
|
52624
|
+
if (ANTIGRAVITY_COMMAND_ACTIONS.has(action)) return toAntigravityCommandTarget(pattern);
|
|
52418
52625
|
if (PATH_ACTIONS.has(action)) return toPathTarget(pattern);
|
|
52419
|
-
if (action
|
|
52626
|
+
if (URL_ACTIONS.has(action)) return toUrlTarget(pattern);
|
|
52420
52627
|
return { target: pattern };
|
|
52421
52628
|
}
|
|
52422
52629
|
/**
|
|
52630
|
+
* The leading directories of a path glob (`src` for `src/*.ts`), or
|
|
52631
|
+
* `undefined` when it has none. A directory target covers everything inside
|
|
52632
|
+
* it, so it matches at least as much as the glob. The filesystem root alone
|
|
52633
|
+
* (`/*`) is not a lead: a deny of it would block every file. Neither is a lead
|
|
52634
|
+
* with `..` in it.
|
|
52635
|
+
*/
|
|
52636
|
+
function toPathLiteralPrefix(pattern) {
|
|
52637
|
+
const path = pattern.startsWith("./") ? pattern.slice(2) : pattern;
|
|
52638
|
+
const prefix = [];
|
|
52639
|
+
for (const segment of path.split("/").slice(0, -1)) {
|
|
52640
|
+
if (hasGlob(segment) || segment.includes("{") || segment.includes("}")) break;
|
|
52641
|
+
prefix.push(segment);
|
|
52642
|
+
}
|
|
52643
|
+
if (prefix.includes("..") || prefix.every((segment) => segment === "" || segment === ".")) return;
|
|
52644
|
+
return prefix.join("/");
|
|
52645
|
+
}
|
|
52646
|
+
/** The widened target of a deny that has no exact Antigravity spelling. */
|
|
52647
|
+
function toWidenedDenyTarget(action, pattern) {
|
|
52648
|
+
if (ANTIGRAVITY_COMMAND_ACTIONS.has(action)) return toAntigravityCommandLiteralPrefix(pattern);
|
|
52649
|
+
if (PATH_ACTIONS.has(action)) return toPathLiteralPrefix(pattern);
|
|
52650
|
+
}
|
|
52651
|
+
/**
|
|
52652
|
+
* Warn about a path target that is a home or variable reference. Antigravity
|
|
52653
|
+
* documents absolute and workspace-relative paths only, so such a reference
|
|
52654
|
+
* may be matched literally and never apply. The entry is still written, since
|
|
52655
|
+
* dropping a deny would lose it where Antigravity does expand the reference.
|
|
52656
|
+
*/
|
|
52657
|
+
function warnHomeOrVariablePath({ action, target, rule, decision, logger, toolLabel }) {
|
|
52658
|
+
if (!PATH_ACTIONS.has(action) || !HOME_OR_VARIABLE_PATH.test(target)) return;
|
|
52659
|
+
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`;
|
|
52660
|
+
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.`);
|
|
52661
|
+
}
|
|
52662
|
+
/**
|
|
52423
52663
|
* Build the entry for one canonical rule, or return `undefined` when
|
|
52424
|
-
* Antigravity cannot express it. A
|
|
52425
|
-
*
|
|
52426
|
-
*
|
|
52427
|
-
*
|
|
52428
|
-
* deny is warned about loudly, because
|
|
52664
|
+
* Antigravity cannot express it. A deny is widened to its literal lead rather
|
|
52665
|
+
* than skipped (`git push * --force` → `command(git push)`, `src/*.ts` →
|
|
52666
|
+
* `read_file(src)`): Antigravity applies deny over ask and allow, so an
|
|
52667
|
+
* overlapping allow that is translated (`git push *`) cannot let through what
|
|
52668
|
+
* the deny was meant to block. A skipped deny is warned about loudly, because
|
|
52669
|
+
* nothing enforces it, and a widened one is warned about too, because it
|
|
52670
|
+
* blocks more than it says.
|
|
52429
52671
|
*/
|
|
52430
52672
|
function buildAntigravityPermissionEntry({ action, category, pattern, decision, logger, toolLabel }) {
|
|
52431
52673
|
const result = pattern === "*" ? { target: "*" } : toTarget(action, pattern);
|
|
52432
52674
|
const rule = `${category}: { "${pattern}": "${decision}" }`;
|
|
52433
52675
|
if ("skipReason" in result) {
|
|
52434
|
-
const prefix =
|
|
52676
|
+
const prefix = decision === "deny" ? toWidenedDenyTarget(action, pattern) : void 0;
|
|
52435
52677
|
if (prefix !== void 0) {
|
|
52436
|
-
|
|
52678
|
+
const scope = PATH_ACTIONS.has(action) ? `every path under \`${prefix}\`` : `every command that starts with \`${prefix}\``;
|
|
52679
|
+
logger.warn(`${toolLabel} permissions: widening ${rule} to ${action}(${prefix}). ${result.skipReason}. The deny now blocks ${scope}, overriding any allow or ask for them.`);
|
|
52680
|
+
warnHomeOrVariablePath({
|
|
52681
|
+
action,
|
|
52682
|
+
target: prefix,
|
|
52683
|
+
rule,
|
|
52684
|
+
decision,
|
|
52685
|
+
logger,
|
|
52686
|
+
toolLabel
|
|
52687
|
+
});
|
|
52437
52688
|
return `${action}(${prefix})`;
|
|
52438
52689
|
}
|
|
52439
52690
|
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`;
|
|
52440
52691
|
logger.warn(`${toolLabel} permissions: skipping ${rule}. ${result.skipReason}. ${consequence}.`);
|
|
52441
52692
|
return;
|
|
52442
52693
|
}
|
|
52443
|
-
if (result.note !== void 0 && decision !== "deny"
|
|
52444
|
-
|
|
52445
|
-
|
|
52446
|
-
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.`);
|
|
52694
|
+
if (result.note !== void 0 && (decision !== "deny" || URL_ACTIONS.has(action))) {
|
|
52695
|
+
const consequence = decision === "deny" ? ", so the deny also overrides any allow or ask there" : "";
|
|
52696
|
+
logger.warn(`${toolLabel} permissions: ${rule}: ${result.note}${consequence}.`);
|
|
52447
52697
|
}
|
|
52698
|
+
warnHomeOrVariablePath({
|
|
52699
|
+
action,
|
|
52700
|
+
target: result.target,
|
|
52701
|
+
rule,
|
|
52702
|
+
decision,
|
|
52703
|
+
logger,
|
|
52704
|
+
toolLabel
|
|
52705
|
+
});
|
|
52448
52706
|
return result.target === "*" ? action : `${action}(${result.target})`;
|
|
52449
52707
|
}
|
|
52450
52708
|
//#endregion
|
|
@@ -52778,7 +53036,8 @@ function pickDocumentedValue({ key, value, documented }) {
|
|
|
52778
53036
|
* Deliberate mapping from rulesync canonical permission categories to the
|
|
52779
53037
|
* Antigravity CLI Fine-Grained Permissions Engine action vocabulary
|
|
52780
53038
|
* (`read_file`, `write_file`, `read_url`, `command`, `mcp`, plus `execute_url` /
|
|
52781
|
-
* `unsandboxed` which have no canonical equivalent and
|
|
53039
|
+
* `unsandboxed` which have no canonical equivalent and keep their names; their
|
|
53040
|
+
* targets are translated like `read_url` / `command` ones). `edit` and
|
|
52782
53041
|
* `write` both map to `write_file`, and `webfetch` / `websearch` both map to
|
|
52783
53042
|
* `read_url`; on import those collapse to the canonical `write` / `webfetch`
|
|
52784
53043
|
* form (a documented, lossy normalization). This shares the action vocabulary of
|
|
@@ -53025,7 +53284,7 @@ function convertAntigravityCliToRulesyncPermissions(params) {
|
|
|
53025
53284
|
for (const entry of entries) {
|
|
53026
53285
|
const { toolName, pattern: target } = parsePermissionEntry$1(entry);
|
|
53027
53286
|
const canonical = toCanonicalToolName$9(toolName);
|
|
53028
|
-
const pattern = toolName
|
|
53287
|
+
const pattern = ANTIGRAVITY_COMMAND_ACTIONS.has(toolName) ? importAntigravityCommandTarget({
|
|
53029
53288
|
target,
|
|
53030
53289
|
entry,
|
|
53031
53290
|
decision: action,
|
|
@@ -53047,7 +53306,8 @@ function convertAntigravityCliToRulesyncPermissions(params) {
|
|
|
53047
53306
|
* Deliberate mapping from rulesync canonical permission categories to the
|
|
53048
53307
|
* Antigravity IDE action vocabulary (`read_file`, `write_file`, `read_url`,
|
|
53049
53308
|
* `command`, `mcp`, plus `execute_url` / `unsandboxed` which have no canonical
|
|
53050
|
-
* equivalent and
|
|
53309
|
+
* equivalent and keep their names; their targets are translated like
|
|
53310
|
+
* `read_url` / `command` ones). `edit` and `write` both map to `write_file`, and
|
|
53051
53311
|
* `webfetch` / `websearch` both map to `read_url`; on import those collapse to
|
|
53052
53312
|
* the canonical `write` / `webfetch` form (a documented, lossy normalization).
|
|
53053
53313
|
*/
|
|
@@ -53249,7 +53509,7 @@ function convertAntigravityIdeToRulesyncPermissions(params) {
|
|
|
53249
53509
|
for (const entry of entries) {
|
|
53250
53510
|
const { action: ideAction, pattern: target } = parsePermissionEntry(entry);
|
|
53251
53511
|
const canonical = toCanonicalCategory$2(ideAction);
|
|
53252
|
-
const pattern = ideAction
|
|
53512
|
+
const pattern = ANTIGRAVITY_COMMAND_ACTIONS.has(ideAction) ? importAntigravityCommandTarget({
|
|
53253
53513
|
target,
|
|
53254
53514
|
entry,
|
|
53255
53515
|
decision: action,
|
|
@@ -72526,6 +72786,335 @@ var PermissionsProcessor = class extends FeatureProcessor {
|
|
|
72526
72786
|
}
|
|
72527
72787
|
};
|
|
72528
72788
|
//#endregion
|
|
72789
|
+
//#region src/types/tool-display.ts
|
|
72790
|
+
const TOOL_DISPLAY = [
|
|
72791
|
+
{
|
|
72792
|
+
key: "agentsmd",
|
|
72793
|
+
label: "AGENTS.md",
|
|
72794
|
+
group: "standard"
|
|
72795
|
+
},
|
|
72796
|
+
{
|
|
72797
|
+
key: "agentsskills",
|
|
72798
|
+
label: "AgentsSkills",
|
|
72799
|
+
group: "standard"
|
|
72800
|
+
},
|
|
72801
|
+
{
|
|
72802
|
+
key: "amp",
|
|
72803
|
+
label: "Amp",
|
|
72804
|
+
group: "ai"
|
|
72805
|
+
},
|
|
72806
|
+
{
|
|
72807
|
+
key: "bob",
|
|
72808
|
+
label: "IBM Bob",
|
|
72809
|
+
group: "ai"
|
|
72810
|
+
},
|
|
72811
|
+
{
|
|
72812
|
+
key: "claudecode",
|
|
72813
|
+
label: "Claude Code",
|
|
72814
|
+
group: "ai"
|
|
72815
|
+
},
|
|
72816
|
+
{
|
|
72817
|
+
key: "claudecode-plugin",
|
|
72818
|
+
label: "Claude Code plugin",
|
|
72819
|
+
group: "ai"
|
|
72820
|
+
},
|
|
72821
|
+
{
|
|
72822
|
+
key: "codebuddy",
|
|
72823
|
+
label: "CodeBuddy Code",
|
|
72824
|
+
group: "ai"
|
|
72825
|
+
},
|
|
72826
|
+
{
|
|
72827
|
+
key: "codewhale",
|
|
72828
|
+
label: "Codewhale",
|
|
72829
|
+
group: "ai"
|
|
72830
|
+
},
|
|
72831
|
+
{
|
|
72832
|
+
key: "codexcli",
|
|
72833
|
+
label: "Codex CLI",
|
|
72834
|
+
group: "ai"
|
|
72835
|
+
},
|
|
72836
|
+
{
|
|
72837
|
+
key: "commandcode",
|
|
72838
|
+
label: "Command Code",
|
|
72839
|
+
group: "ai"
|
|
72840
|
+
},
|
|
72841
|
+
{
|
|
72842
|
+
key: "copilot",
|
|
72843
|
+
label: "GitHub Copilot",
|
|
72844
|
+
group: "ai"
|
|
72845
|
+
},
|
|
72846
|
+
{
|
|
72847
|
+
key: "copilotcli",
|
|
72848
|
+
label: "GitHub Copilot CLI",
|
|
72849
|
+
group: "ai"
|
|
72850
|
+
},
|
|
72851
|
+
{
|
|
72852
|
+
key: "crush",
|
|
72853
|
+
label: "Crush",
|
|
72854
|
+
group: "ai"
|
|
72855
|
+
},
|
|
72856
|
+
{
|
|
72857
|
+
key: "goose",
|
|
72858
|
+
label: "Goose",
|
|
72859
|
+
group: "ai"
|
|
72860
|
+
},
|
|
72861
|
+
{
|
|
72862
|
+
key: "hermesagent",
|
|
72863
|
+
label: "Hermes Agent",
|
|
72864
|
+
group: "ai"
|
|
72865
|
+
},
|
|
72866
|
+
{
|
|
72867
|
+
key: "grokcli",
|
|
72868
|
+
label: "Grok CLI",
|
|
72869
|
+
group: "ai"
|
|
72870
|
+
},
|
|
72871
|
+
{
|
|
72872
|
+
key: "cursor",
|
|
72873
|
+
label: "Cursor",
|
|
72874
|
+
group: "ai"
|
|
72875
|
+
},
|
|
72876
|
+
{
|
|
72877
|
+
key: "deepagents",
|
|
72878
|
+
label: "deepagents-cli",
|
|
72879
|
+
group: "ai"
|
|
72880
|
+
},
|
|
72881
|
+
{
|
|
72882
|
+
key: "factorydroid",
|
|
72883
|
+
label: "Factory Droid",
|
|
72884
|
+
group: "ai"
|
|
72885
|
+
},
|
|
72886
|
+
{
|
|
72887
|
+
key: "opencode",
|
|
72888
|
+
label: "OpenCode",
|
|
72889
|
+
group: "ai"
|
|
72890
|
+
},
|
|
72891
|
+
{
|
|
72892
|
+
key: "openclaw",
|
|
72893
|
+
label: "OpenClaw",
|
|
72894
|
+
group: "ai"
|
|
72895
|
+
},
|
|
72896
|
+
{
|
|
72897
|
+
key: "mimocode",
|
|
72898
|
+
label: "MiMo Code",
|
|
72899
|
+
group: "ai"
|
|
72900
|
+
},
|
|
72901
|
+
{
|
|
72902
|
+
key: "gitlabduo",
|
|
72903
|
+
label: "GitLab Duo CLI",
|
|
72904
|
+
group: "ai"
|
|
72905
|
+
},
|
|
72906
|
+
{
|
|
72907
|
+
key: "cline",
|
|
72908
|
+
label: "Cline",
|
|
72909
|
+
group: "ai"
|
|
72910
|
+
},
|
|
72911
|
+
{
|
|
72912
|
+
key: "kilo",
|
|
72913
|
+
label: "Kilo Code",
|
|
72914
|
+
group: "ai"
|
|
72915
|
+
},
|
|
72916
|
+
{
|
|
72917
|
+
key: "kimi-code",
|
|
72918
|
+
label: "Kimi Code",
|
|
72919
|
+
group: "ai"
|
|
72920
|
+
},
|
|
72921
|
+
{
|
|
72922
|
+
key: "kimi-code-plugin",
|
|
72923
|
+
label: "Kimi Code plugin",
|
|
72924
|
+
group: "ai"
|
|
72925
|
+
},
|
|
72926
|
+
{
|
|
72927
|
+
key: "roo",
|
|
72928
|
+
label: "Roo Code ⚠️",
|
|
72929
|
+
group: "ai"
|
|
72930
|
+
},
|
|
72931
|
+
{
|
|
72932
|
+
key: "zoocode",
|
|
72933
|
+
label: "Zoo Code",
|
|
72934
|
+
group: "ai"
|
|
72935
|
+
},
|
|
72936
|
+
{
|
|
72937
|
+
key: "rovodev",
|
|
72938
|
+
label: "Rovodev (Atlassian) ⚠️",
|
|
72939
|
+
group: "ai"
|
|
72940
|
+
},
|
|
72941
|
+
{
|
|
72942
|
+
key: "takt",
|
|
72943
|
+
label: "Takt",
|
|
72944
|
+
group: "ai"
|
|
72945
|
+
},
|
|
72946
|
+
{
|
|
72947
|
+
key: "trae",
|
|
72948
|
+
label: "Trae",
|
|
72949
|
+
group: "ai"
|
|
72950
|
+
},
|
|
72951
|
+
{
|
|
72952
|
+
key: "tabnine",
|
|
72953
|
+
label: "Tabnine CLI ⚠️",
|
|
72954
|
+
group: "ai"
|
|
72955
|
+
},
|
|
72956
|
+
{
|
|
72957
|
+
key: "continue",
|
|
72958
|
+
label: "Continue ⚠️",
|
|
72959
|
+
group: "ai"
|
|
72960
|
+
},
|
|
72961
|
+
{
|
|
72962
|
+
key: "cortexcode",
|
|
72963
|
+
label: "Snowflake Cortex Code",
|
|
72964
|
+
group: "ai"
|
|
72965
|
+
},
|
|
72966
|
+
{
|
|
72967
|
+
key: "vibe",
|
|
72968
|
+
label: "Vibe Code",
|
|
72969
|
+
group: "ai"
|
|
72970
|
+
},
|
|
72971
|
+
{
|
|
72972
|
+
key: "vibe-plugin",
|
|
72973
|
+
label: "Vibe Code plugin",
|
|
72974
|
+
group: "ai"
|
|
72975
|
+
},
|
|
72976
|
+
{
|
|
72977
|
+
key: "qoder",
|
|
72978
|
+
label: "Qoder",
|
|
72979
|
+
group: "ai"
|
|
72980
|
+
},
|
|
72981
|
+
{
|
|
72982
|
+
key: "qwencode",
|
|
72983
|
+
label: "Qwen Code",
|
|
72984
|
+
group: "ai"
|
|
72985
|
+
},
|
|
72986
|
+
{
|
|
72987
|
+
key: "musecode",
|
|
72988
|
+
label: "Meta Muse Code",
|
|
72989
|
+
group: "ai"
|
|
72990
|
+
},
|
|
72991
|
+
{
|
|
72992
|
+
key: "reasonix",
|
|
72993
|
+
label: "Reasonix",
|
|
72994
|
+
group: "ai"
|
|
72995
|
+
},
|
|
72996
|
+
{
|
|
72997
|
+
key: "codebuff",
|
|
72998
|
+
label: "Codebuff (Freebuff)",
|
|
72999
|
+
group: "ai"
|
|
73000
|
+
},
|
|
73001
|
+
{
|
|
73002
|
+
key: "kiro",
|
|
73003
|
+
label: "Kiro ⚠️",
|
|
73004
|
+
group: "ai"
|
|
73005
|
+
},
|
|
73006
|
+
{
|
|
73007
|
+
key: "kiro-cli",
|
|
73008
|
+
label: "Kiro CLI",
|
|
73009
|
+
group: "ai"
|
|
73010
|
+
},
|
|
73011
|
+
{
|
|
73012
|
+
key: "kiro-ide",
|
|
73013
|
+
label: "Kiro IDE",
|
|
73014
|
+
group: "ai"
|
|
73015
|
+
},
|
|
73016
|
+
{
|
|
73017
|
+
key: "lettacode",
|
|
73018
|
+
label: "Letta Code",
|
|
73019
|
+
group: "ai"
|
|
73020
|
+
},
|
|
73021
|
+
{
|
|
73022
|
+
key: "antigravity-ide",
|
|
73023
|
+
label: "Google Antigravity IDE",
|
|
73024
|
+
group: "ai"
|
|
73025
|
+
},
|
|
73026
|
+
{
|
|
73027
|
+
key: "antigravity-cli",
|
|
73028
|
+
label: "Google Antigravity CLI",
|
|
73029
|
+
group: "ai"
|
|
73030
|
+
},
|
|
73031
|
+
{
|
|
73032
|
+
key: "antigravity-plugin",
|
|
73033
|
+
label: "Google Antigravity plugin",
|
|
73034
|
+
group: "ai"
|
|
73035
|
+
},
|
|
73036
|
+
{
|
|
73037
|
+
key: "aiassistant",
|
|
73038
|
+
label: "JetBrains AI Assistant",
|
|
73039
|
+
group: "ai"
|
|
73040
|
+
},
|
|
73041
|
+
{
|
|
73042
|
+
key: "junie",
|
|
73043
|
+
label: "JetBrains Junie",
|
|
73044
|
+
group: "ai"
|
|
73045
|
+
},
|
|
73046
|
+
{
|
|
73047
|
+
key: "augmentcode",
|
|
73048
|
+
label: "AugmentCode",
|
|
73049
|
+
group: "ai"
|
|
73050
|
+
},
|
|
73051
|
+
{
|
|
73052
|
+
key: "augmentcode-plugin",
|
|
73053
|
+
label: "AugmentCode plugin",
|
|
73054
|
+
group: "ai"
|
|
73055
|
+
},
|
|
73056
|
+
{
|
|
73057
|
+
key: "devin",
|
|
73058
|
+
label: "Devin Desktop",
|
|
73059
|
+
group: "ai"
|
|
73060
|
+
},
|
|
73061
|
+
{
|
|
73062
|
+
key: "devin-plugin",
|
|
73063
|
+
label: "Devin plugin",
|
|
73064
|
+
group: "ai"
|
|
73065
|
+
},
|
|
73066
|
+
{
|
|
73067
|
+
key: "warp",
|
|
73068
|
+
label: "Warp",
|
|
73069
|
+
group: "ai"
|
|
73070
|
+
},
|
|
73071
|
+
{
|
|
73072
|
+
key: "warpcli",
|
|
73073
|
+
label: "Warp Agent CLI",
|
|
73074
|
+
group: "ai"
|
|
73075
|
+
},
|
|
73076
|
+
{
|
|
73077
|
+
key: "replit",
|
|
73078
|
+
label: "Replit",
|
|
73079
|
+
group: "ai"
|
|
73080
|
+
},
|
|
73081
|
+
{
|
|
73082
|
+
key: "pi",
|
|
73083
|
+
label: "Pi Coding Agent",
|
|
73084
|
+
group: "ai"
|
|
73085
|
+
},
|
|
73086
|
+
{
|
|
73087
|
+
key: "omp",
|
|
73088
|
+
label: "oh-my-pi",
|
|
73089
|
+
group: "ai"
|
|
73090
|
+
},
|
|
73091
|
+
{
|
|
73092
|
+
key: "zed",
|
|
73093
|
+
label: "Zed",
|
|
73094
|
+
group: "ai"
|
|
73095
|
+
},
|
|
73096
|
+
{
|
|
73097
|
+
key: "zcode",
|
|
73098
|
+
label: "ZCode (Z.ai)",
|
|
73099
|
+
group: "ai"
|
|
73100
|
+
},
|
|
73101
|
+
{
|
|
73102
|
+
key: "zcode-plugin",
|
|
73103
|
+
label: "ZCode plugin",
|
|
73104
|
+
group: "ai"
|
|
73105
|
+
},
|
|
73106
|
+
{
|
|
73107
|
+
key: "pool",
|
|
73108
|
+
label: "Pool (Poolside)",
|
|
73109
|
+
group: "ai"
|
|
73110
|
+
},
|
|
73111
|
+
{
|
|
73112
|
+
key: "dsh",
|
|
73113
|
+
label: "DeepSeek Harness",
|
|
73114
|
+
group: "ai"
|
|
73115
|
+
}
|
|
73116
|
+
];
|
|
73117
|
+
//#endregion
|
|
72529
73118
|
//#region src/features/skills/simulated-skill.ts
|
|
72530
73119
|
const SimulatedSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
72531
73120
|
name: zod_mini.z.string(),
|
|
@@ -84871,7 +85460,7 @@ var DeepagentsSubagent = class DeepagentsSubagent extends ToolSubagent {
|
|
|
84871
85460
|
//#endregion
|
|
84872
85461
|
//#region src/features/subagents/devin-subagent.ts
|
|
84873
85462
|
const DevinSubagentFrontmatterSchema = zod_mini.z.looseObject({
|
|
84874
|
-
name: zod_mini.z.string(),
|
|
85463
|
+
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
84875
85464
|
description: zod_mini.z.optional(zod_mini.z.string()),
|
|
84876
85465
|
model: zod_mini.z.optional(zod_mini.z.string()),
|
|
84877
85466
|
"allowed-tools": zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string())),
|
|
@@ -84924,7 +85513,7 @@ var DevinSubagent = class extends ToolSubagent {
|
|
|
84924
85513
|
outputRoot: ".",
|
|
84925
85514
|
frontmatter: {
|
|
84926
85515
|
targets: ["*"],
|
|
84927
|
-
name,
|
|
85516
|
+
name: name ?? this.getSubagentName(),
|
|
84928
85517
|
description,
|
|
84929
85518
|
...Object.keys(devinSection).length > 0 && { devin: devinSection }
|
|
84930
85519
|
},
|
|
@@ -84998,7 +85587,8 @@ var DevinSubagent = class extends ToolSubagent {
|
|
|
84998
85587
|
const paths = this.getSettablePaths({ global });
|
|
84999
85588
|
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
85000
85589
|
const fileContent = await readFileContent(filePath);
|
|
85001
|
-
const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
|
|
85590
|
+
const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(fileContent, filePath);
|
|
85591
|
+
if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${filePath}`);
|
|
85002
85592
|
const result = DevinSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
85003
85593
|
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
85004
85594
|
return new this({
|
|
@@ -98646,6 +99236,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
98646
99236
|
warnForOutputStyleRuleOptions({ rules, factory }) {
|
|
98647
99237
|
const toolTarget = this.toolTarget;
|
|
98648
99238
|
if (toolTarget !== "factorydroid" && toolTarget !== "qoder") return;
|
|
99239
|
+
const toolLabel = TOOL_DISPLAY.find((entry) => entry.key === toolTarget)?.label ?? toolTarget;
|
|
98649
99240
|
for (const rule of rules) {
|
|
98650
99241
|
const frontmatter = rule.getFrontmatter();
|
|
98651
99242
|
const section = frontmatter[toolTarget];
|
|
@@ -98653,7 +99244,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
98653
99244
|
const { channel, name } = section;
|
|
98654
99245
|
const fileName = stripControlCharacters(rule.getRelativeFilePath());
|
|
98655
99246
|
const targets = frontmatter.targets ?? ["*"];
|
|
98656
|
-
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 ${
|
|
99247
|
+
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}.`);
|
|
98657
99248
|
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.`);
|
|
98658
99249
|
}
|
|
98659
99250
|
}
|
|
@@ -103053,10 +103644,10 @@ Object.defineProperty(exports, "generate", {
|
|
|
103053
103644
|
return generate;
|
|
103054
103645
|
}
|
|
103055
103646
|
});
|
|
103056
|
-
Object.defineProperty(exports, "
|
|
103647
|
+
Object.defineProperty(exports, "getFileSizeAndExecutableBit", {
|
|
103057
103648
|
enumerable: true,
|
|
103058
103649
|
get: function() {
|
|
103059
|
-
return
|
|
103650
|
+
return getFileSizeAndExecutableBit;
|
|
103060
103651
|
}
|
|
103061
103652
|
});
|
|
103062
103653
|
Object.defineProperty(exports, "getHomeDirectory", {
|
|
@@ -103101,12 +103692,6 @@ Object.defineProperty(exports, "hasEnclosingMarkOutsideKeycap", {
|
|
|
103101
103692
|
return hasEnclosingMarkOutsideKeycap;
|
|
103102
103693
|
}
|
|
103103
103694
|
});
|
|
103104
|
-
Object.defineProperty(exports, "hasExecutableBit", {
|
|
103105
|
-
enumerable: true,
|
|
103106
|
-
get: function() {
|
|
103107
|
-
return hasExecutableBit;
|
|
103108
|
-
}
|
|
103109
|
-
});
|
|
103110
103695
|
Object.defineProperty(exports, "importFromTool", {
|
|
103111
103696
|
enumerable: true,
|
|
103112
103697
|
get: function() {
|
|
@@ -103191,6 +103776,12 @@ Object.defineProperty(exports, "pathEscapesRoot", {
|
|
|
103191
103776
|
return pathEscapesRoot;
|
|
103192
103777
|
}
|
|
103193
103778
|
});
|
|
103779
|
+
Object.defineProperty(exports, "posixRelativePathEscapesRoot", {
|
|
103780
|
+
enumerable: true,
|
|
103781
|
+
get: function() {
|
|
103782
|
+
return posixRelativePathEscapesRoot;
|
|
103783
|
+
}
|
|
103784
|
+
});
|
|
103194
103785
|
Object.defineProperty(exports, "quoteForLog", {
|
|
103195
103786
|
enumerable: true,
|
|
103196
103787
|
get: function() {
|
|
@@ -103263,10 +103854,10 @@ Object.defineProperty(exports, "resolveRulesyncSourceWritePath", {
|
|
|
103263
103854
|
return resolveRulesyncSourceWritePath;
|
|
103264
103855
|
}
|
|
103265
103856
|
});
|
|
103266
|
-
Object.defineProperty(exports, "
|
|
103857
|
+
Object.defineProperty(exports, "resolvedRelativePath", {
|
|
103267
103858
|
enumerable: true,
|
|
103268
103859
|
get: function() {
|
|
103269
|
-
return
|
|
103860
|
+
return resolvedRelativePath;
|
|
103270
103861
|
}
|
|
103271
103862
|
});
|
|
103272
103863
|
Object.defineProperty(exports, "runWithDirectoryRollback", {
|