rulesync 14.2.0 → 15.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -39
- package/dist/cli/index.cjs +84 -85
- package/dist/cli/index.js +84 -85
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-CMCy95RI.js → import-BuxzyDyH.js} +1889 -303
- package/dist/import-BuxzyDyH.js.map +1 -0
- package/dist/{import-Ds8vYv6h.cjs → import-DRN7goJ_.cjs} +1932 -316
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/import-CMCy95RI.js.map +0 -1
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ See [Installation docs](https://dyoshikawa.github.io/rulesync/getting-started/in
|
|
|
53
53
|
rulesync init
|
|
54
54
|
|
|
55
55
|
# Install official skills (recommended)
|
|
56
|
-
rulesync fetch dyoshikawa/rulesync
|
|
56
|
+
rulesync fetch dyoshikawa/rulesync
|
|
57
57
|
|
|
58
58
|
# Generate unified configurations with all features
|
|
59
59
|
rulesync generate --targets "*" --features "*"
|
|
@@ -86,41 +86,44 @@ The tables below show whether each tool supports a given feature (✅ = supporte
|
|
|
86
86
|
|
|
87
87
|
<!-- SUPPORTED_TOOLS_AI:BEGIN -->
|
|
88
88
|
|
|
89
|
-
| Tool
|
|
90
|
-
|
|
|
91
|
-
| Amp
|
|
92
|
-
| Claude Code
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
| GitHub Copilot
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
| Kiro
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
89
|
+
| Tool | rules | ignore | mcp | commands | subagents | skills | hooks | permissions | checks |
|
|
90
|
+
| ------------------------- | :---: | :----: | :-: | :------: | :-------: | :----: | :---: | :---------: | :----: |
|
|
91
|
+
| Amp | ✅ | | ✅ | | | ✅ | ✅ | ✅ | ✅ |
|
|
92
|
+
| Claude Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
93
|
+
| Claude Code plugin | | | ✅ | ✅ | ✅ | ✅ | ✅ | | |
|
|
94
|
+
| Codex CLI | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
95
|
+
| GitHub Copilot | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
96
|
+
| GitHub Copilot CLI | ✅ | | ✅ | | ✅ | ✅ | ✅ | | |
|
|
97
|
+
| Goose | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
98
|
+
| Hermes Agent | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
99
|
+
| Grok CLI | ✅ | | ✅ | | ✅ | ✅ | ✅ | ✅ | |
|
|
100
|
+
| Cursor | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
101
|
+
| deepagents-cli | ✅ | | ✅ | | ✅ | ✅ | ✅ | | |
|
|
102
|
+
| Factory Droid | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
103
|
+
| OpenCode | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
104
|
+
| Cline | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | ✅ | |
|
|
105
|
+
| Kilo Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
106
|
+
| Kimi Code | ✅ | | ✅ | | ✅ | ✅ | ✅ | ✅ | |
|
|
107
|
+
| Roo Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | |
|
|
108
|
+
| Rovodev (Atlassian) | ✅ | | ✅ | ✅ | ✅ | ✅ | | ✅ | |
|
|
109
|
+
| Takt | ✅ | | ✅ | ✅ | ✅ | ✅ | | ✅ | |
|
|
110
|
+
| Vibe Code | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | |
|
|
111
|
+
| Qwen Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
112
|
+
| Reasonix | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
113
|
+
| Kiro ⚠️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
114
|
+
| Kiro CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
115
|
+
| Kiro IDE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
116
|
+
| Google Antigravity IDE | ✅ | | ✅ | ✅ | | ✅ | ✅ | ✅ | |
|
|
117
|
+
| Google Antigravity CLI | ✅ | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | |
|
|
118
|
+
| Google Antigravity plugin | ✅ | | ✅ | | | ✅ | ✅ | | |
|
|
119
|
+
| JetBrains AI Assistant | ✅ | ✅ | ✅ | | | ✅ | | | |
|
|
120
|
+
| JetBrains Junie | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
121
|
+
| AugmentCode | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
122
|
+
| Devin Desktop | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
|
123
|
+
| Warp | ✅ | ✅ | ✅ | | | ✅ | | ✅ | |
|
|
124
|
+
| Replit | ✅ | | | | | ✅ | | | |
|
|
125
|
+
| Pi Coding Agent | ✅ | | | ✅ | | ✅ | ✅ | | |
|
|
126
|
+
| Zed | ✅ | ✅ | ✅ | | | ✅ | | ✅ | |
|
|
124
127
|
|
|
125
128
|
<!-- SUPPORTED_TOOLS_AI:END -->
|
|
126
129
|
|
|
@@ -137,12 +140,14 @@ The tables below show whether each tool supports a given feature (✅ = supporte
|
|
|
137
140
|
|
|
138
141
|
- ⚠️: Deprecated — still supported, but see the note below
|
|
139
142
|
|
|
140
|
-
###
|
|
143
|
+
### Target and deprecation notes
|
|
141
144
|
|
|
145
|
+
- **Ignore feature** — The `ignore` feature is deprecated in favor of the more expressive `permissions` feature. Existing ignore configurations remain supported throughout Rulesync 14.x; removal, if any, will be decided separately and will not occur before a future major release. New `rulesync init` projects scaffold permissions without enabling or creating ignore files. See the [migration guide](https://dyoshikawa.github.io/rulesync/reference/file-formats#rulesync-aiignore-or-rulesyncignore-deprecated).
|
|
142
146
|
- **Google Antigravity (`antigravity-ide` / `antigravity-cli`)** — Antigravity 2.0 splits into two products with separate global config trees: the desktop **`antigravity-ide`** and the **`antigravity-cli`** (`agy`). For project-scope rules, **both `antigravity-ide` and `antigravity-cli`** emit the root rule as a plain cross-tool **`AGENTS.md`** at the project root (the Gemini-lineage discovery order is `AGENTS.md`, `CONTEXT.md`, `GEMINI.md`; the IDE has read `AGENTS.md` since v1.20.3) and non-root rules under `.agents/rules/`.
|
|
143
|
-
- **
|
|
147
|
+
- **Plugin packaging (`claudecode-plugin` / `antigravity-plugin`)** — These project-only targets generate and import Rulesync-managed components inside an existing plugin directory selected with `--output-roots` (generate) or `--output-root` (import). They are excluded from `--targets "*"` to avoid writing package-level `skills/`, `rules/`, or `commands/` directories into ordinary projects. Rulesync preserves plugin manifests, marketplace metadata, scripts, and other non-component assets. See the [Plugin Packaging guide](https://dyoshikawa.github.io/rulesync/guide/plugin-packaging).
|
|
148
|
+
- **Kiro (`kiro`)** — Kiro's IDE and CLI use diverging config formats (IDE: Markdown subagents `.kiro/agents/*.md` and structured JSON hooks `.kiro/hooks/*.json`; CLI: JSON agent-config subagents `.kiro/agents/*.json` and hooks in `.kiro/agents/default.json`), so `kiro` is split into **`kiro-cli`** and **`kiro-ide`**. The legacy `kiro` target remains as a **deprecated alias** with its current behavior unchanged. The two targets share every surface except **subagents** (Markdown vs JSON) and **hooks**; Kiro IDE hooks are emitted as a single `.kiro/hooks/rulesync.json` (`{ "version": "v1", "hooks": [ ... ] }`) in project (`.kiro/hooks/`) and global (`~/.kiro/hooks/`) scope, while the CLI uses `.kiro/agents/default.json`. Global skills (`~/.kiro/skills/`), global ignore (`~/.kiro/settings/kiroignore`), and global Kiro IDE subagents (`~/.kiro/agents/`) are supported too, as are global Kiro CLI commands (`~/.kiro/prompts/`) and subagents (`~/.kiro/agents/`). Kiro MCP generation preserves per-server `disabledTools`, and Kiro CLI hook caching maps `cacheTtl` to `cache_ttl_seconds`.
|
|
144
149
|
|
|
145
|
-
Some features accept per-feature options
|
|
150
|
+
Some features accept per-feature options. See [Configuration > Per-feature options](https://dyoshikawa.github.io/rulesync/guide/configuration#per-feature-options) for details.
|
|
146
151
|
|
|
147
152
|
## Documentation
|
|
148
153
|
|
package/dist/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_import = require("../import-
|
|
2
|
+
const require_import = require("../import-DRN7goJ_.cjs");
|
|
3
3
|
let commander = require("commander");
|
|
4
4
|
let zod_mini = require("zod/mini");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -278,8 +278,14 @@ function singletonTemplate(feature) {
|
|
|
278
278
|
"src/**": "allow"
|
|
279
279
|
},
|
|
280
280
|
"read": {
|
|
281
|
-
".env": "deny"
|
|
281
|
+
".env": "deny",
|
|
282
|
+
"credentials/**": "deny"
|
|
282
283
|
}
|
|
284
|
+
},
|
|
285
|
+
"codexcli": {
|
|
286
|
+
"approval_policy": "on-request",
|
|
287
|
+
"approvals_reviewer": "auto_review",
|
|
288
|
+
"base_permission_profile": ":danger-full-access"
|
|
283
289
|
}
|
|
284
290
|
}
|
|
285
291
|
`;
|
|
@@ -319,25 +325,19 @@ function createFeatureScaffold({ feature, name }) {
|
|
|
319
325
|
});
|
|
320
326
|
case "mcp": {
|
|
321
327
|
const paths = require_import.RulesyncMcp.getSettablePaths();
|
|
322
|
-
const relativeFilePath = (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath);
|
|
323
328
|
return {
|
|
324
329
|
feature,
|
|
325
|
-
relativeFilePath,
|
|
326
|
-
candidateRelativeFilePaths:
|
|
327
|
-
...paths.jsonc ? [(0, node_path.join)(paths.jsonc.relativeDirPath, paths.jsonc.relativeFilePath)] : [],
|
|
328
|
-
relativeFilePath,
|
|
329
|
-
...paths.legacy ? [(0, node_path.join)(paths.legacy.relativeDirPath, paths.legacy.relativeFilePath)] : []
|
|
330
|
-
],
|
|
330
|
+
relativeFilePath: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath),
|
|
331
|
+
candidateRelativeFilePaths: require_import.getRulesyncSourceCandidates({ paths }).map((candidate) => (0, node_path.join)(candidate.relativeDirPath, candidate.relativeFilePath)),
|
|
331
332
|
content: singletonTemplate(feature)
|
|
332
333
|
};
|
|
333
334
|
}
|
|
334
335
|
case "hooks": {
|
|
335
336
|
const paths = require_import.RulesyncHooks.getSettablePaths();
|
|
336
|
-
const relativeFilePath = (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath);
|
|
337
337
|
return {
|
|
338
338
|
feature,
|
|
339
|
-
relativeFilePath,
|
|
340
|
-
candidateRelativeFilePaths:
|
|
339
|
+
relativeFilePath: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath),
|
|
340
|
+
candidateRelativeFilePaths: require_import.getRulesyncSourceCandidates({ paths }).map((candidate) => (0, node_path.join)(candidate.relativeDirPath, candidate.relativeFilePath)),
|
|
341
341
|
content: singletonTemplate(feature)
|
|
342
342
|
};
|
|
343
343
|
}
|
|
@@ -353,11 +353,10 @@ function createFeatureScaffold({ feature, name }) {
|
|
|
353
353
|
}
|
|
354
354
|
case "permissions": {
|
|
355
355
|
const paths = require_import.RulesyncPermissions.getSettablePaths();
|
|
356
|
-
const relativeFilePath = (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath);
|
|
357
356
|
return {
|
|
358
357
|
feature,
|
|
359
|
-
relativeFilePath,
|
|
360
|
-
candidateRelativeFilePaths:
|
|
358
|
+
relativeFilePath: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath),
|
|
359
|
+
candidateRelativeFilePaths: require_import.getRulesyncSourceCandidates({ paths }).map((candidate) => (0, node_path.join)(candidate.relativeDirPath, candidate.relativeFilePath)),
|
|
361
360
|
content: singletonTemplate(feature)
|
|
362
361
|
};
|
|
363
362
|
}
|
|
@@ -3797,6 +3796,8 @@ async function convertCommand(logger, options) {
|
|
|
3797
3796
|
const fromTool = parseToolTarget$1(options.from ?? "", "source");
|
|
3798
3797
|
const toToolsRaw = (options.to ?? []).map((t) => parseToolTarget$1(t, "destination"));
|
|
3799
3798
|
const toTools = Array.from(new Set(toToolsRaw));
|
|
3799
|
+
const packagingTarget = [fromTool, ...toTools].find(require_import.isPackagingToolTarget);
|
|
3800
|
+
if (packagingTarget) throw new require_import.CLIError(`Plugin packaging target '${packagingTarget}' is not supported by convert. Use import --output-root and generate --output-roots with an explicit plugin directory.`, require_import.ErrorCodes.CONVERT_FAILED);
|
|
3800
3801
|
if (toTools.includes(fromTool)) throw new require_import.CLIError(`Destination tools must not include the source tool '${fromTool}'. Converting a tool onto itself is likely a mistake and may cause lossy round-trips.`, require_import.ErrorCodes.CONVERT_FAILED);
|
|
3801
3802
|
const config = await require_import.ConfigResolver.resolve({
|
|
3802
3803
|
...options,
|
|
@@ -3861,9 +3862,9 @@ const FEATURE_PATHS = {
|
|
|
3861
3862
|
skills: ["skills"],
|
|
3862
3863
|
checks: ["checks"],
|
|
3863
3864
|
ignore: [require_import.RULESYNC_AIIGNORE_FILE_NAME],
|
|
3864
|
-
mcp: [require_import.RULESYNC_MCP_FILE_NAME, require_import.
|
|
3865
|
-
hooks: [require_import.RULESYNC_HOOKS_FILE_NAME, require_import.
|
|
3866
|
-
permissions: [require_import.RULESYNC_PERMISSIONS_FILE_NAME, require_import.
|
|
3865
|
+
mcp: [require_import.RULESYNC_MCP_FILE_NAME, require_import.RULESYNC_MCP_LEGACY_FILE_NAME],
|
|
3866
|
+
hooks: [require_import.RULESYNC_HOOKS_FILE_NAME, require_import.RULESYNC_HOOKS_LEGACY_FILE_NAME],
|
|
3867
|
+
permissions: [require_import.RULESYNC_PERMISSIONS_FILE_NAME, require_import.RULESYNC_PERMISSIONS_LEGACY_FILE_NAME]
|
|
3867
3868
|
};
|
|
3868
3869
|
/**
|
|
3869
3870
|
* Check if target is a tool target (not rulesync)
|
|
@@ -4001,10 +4002,11 @@ async function convertFetchedFilesToRulesync(params) {
|
|
|
4001
4002
|
};
|
|
4002
4003
|
}
|
|
4003
4004
|
/**
|
|
4004
|
-
* Resolve features from options, handling wildcard
|
|
4005
|
+
* Resolve features from options, defaulting to skills and handling wildcard.
|
|
4005
4006
|
*/
|
|
4006
4007
|
function resolveFeatures(features) {
|
|
4007
|
-
if (
|
|
4008
|
+
if (features === void 0) return ["skills"];
|
|
4009
|
+
if (features.includes("*")) return [...require_import.ALL_FEATURES];
|
|
4008
4010
|
return features.filter((f) => require_import.ALL_FEATURES.includes(f));
|
|
4009
4011
|
}
|
|
4010
4012
|
/**
|
|
@@ -4823,6 +4825,7 @@ const ALL_GITIGNORE_ENTRIES = (() => {
|
|
|
4823
4825
|
const seen = /* @__PURE__ */ new Set();
|
|
4824
4826
|
const result = [];
|
|
4825
4827
|
for (const tag of GITIGNORE_ENTRY_REGISTRY) {
|
|
4828
|
+
if (normalizeGitignoreEntryTargets(tag.target).every((target) => require_import.PACKAGING_TOOL_TARGETS.includes(target))) continue;
|
|
4826
4829
|
if (seen.has(tag.entry)) continue;
|
|
4827
4830
|
seen.add(tag.entry);
|
|
4828
4831
|
result.push(tag.entry);
|
|
@@ -4832,14 +4835,13 @@ const ALL_GITIGNORE_ENTRIES = (() => {
|
|
|
4832
4835
|
const isTargetSelected = (target, selectedTargets) => {
|
|
4833
4836
|
const targets = normalizeGitignoreEntryTargets(target);
|
|
4834
4837
|
if (targets.includes("common")) return true;
|
|
4835
|
-
if (!selectedTargets || selectedTargets.length === 0) return
|
|
4836
|
-
if (selectedTargets.includes("*")) return true;
|
|
4838
|
+
if (!selectedTargets || selectedTargets.length === 0 || selectedTargets.includes("*")) return targets.some((candidate) => selectedTargets?.includes(candidate) || !require_import.PACKAGING_TOOL_TARGETS.includes(candidate));
|
|
4837
4839
|
return targets.some((candidate) => selectedTargets.includes(candidate));
|
|
4838
4840
|
};
|
|
4839
4841
|
const getSelectedGitignoreEntryTargets = (target, selectedTargets) => {
|
|
4840
4842
|
const targets = normalizeGitignoreEntryTargets(target);
|
|
4841
4843
|
if (targets.includes("common")) return ["common"];
|
|
4842
|
-
if (!selectedTargets || selectedTargets.length === 0 || selectedTargets.includes("*")) return targets;
|
|
4844
|
+
if (!selectedTargets || selectedTargets.length === 0 || selectedTargets.includes("*")) return targets.filter((candidate) => selectedTargets?.includes(candidate) || !require_import.PACKAGING_TOOL_TARGETS.includes(candidate));
|
|
4843
4845
|
return targets.filter((candidate) => selectedTargets.includes(candidate));
|
|
4844
4846
|
};
|
|
4845
4847
|
const isFeatureSelected = (feature, features) => {
|
|
@@ -5160,16 +5162,13 @@ async function createConfigFile() {
|
|
|
5160
5162
|
await require_import.writeFileContent(path, JSON.stringify({
|
|
5161
5163
|
$schema: require_import.RULESYNC_CONFIG_SCHEMA_URL,
|
|
5162
5164
|
targets: [
|
|
5163
|
-
"
|
|
5164
|
-
"cursor",
|
|
5165
|
+
"codexcli",
|
|
5165
5166
|
"claudecode",
|
|
5166
|
-
"
|
|
5167
|
+
"opencode"
|
|
5167
5168
|
],
|
|
5168
5169
|
features: [
|
|
5169
5170
|
"rules",
|
|
5170
|
-
"ignore",
|
|
5171
5171
|
"mcp",
|
|
5172
|
-
"commands",
|
|
5173
5172
|
"subagents",
|
|
5174
5173
|
"skills",
|
|
5175
5174
|
"hooks",
|
|
@@ -5197,10 +5196,6 @@ async function createSampleFiles() {
|
|
|
5197
5196
|
name: "overview"
|
|
5198
5197
|
}),
|
|
5199
5198
|
createFeatureScaffold({ feature: "mcp" }),
|
|
5200
|
-
createFeatureScaffold({
|
|
5201
|
-
feature: "command",
|
|
5202
|
-
name: "review-pr"
|
|
5203
|
-
}),
|
|
5204
5199
|
createFeatureScaffold({
|
|
5205
5200
|
feature: "subagent",
|
|
5206
5201
|
name: "planner"
|
|
@@ -5209,21 +5204,24 @@ async function createSampleFiles() {
|
|
|
5209
5204
|
feature: "skill",
|
|
5210
5205
|
name: "project-context"
|
|
5211
5206
|
}),
|
|
5212
|
-
createFeatureScaffold({ feature: "ignore" }),
|
|
5213
5207
|
createFeatureScaffold({ feature: "hooks" }),
|
|
5214
5208
|
createFeatureScaffold({ feature: "permissions" })
|
|
5215
5209
|
];
|
|
5216
5210
|
const results = [];
|
|
5217
5211
|
for (const sample of samples) {
|
|
5218
5212
|
await require_import.ensureDir((0, node_path.dirname)(sample.relativeFilePath));
|
|
5219
|
-
results.push(await writeIfNotExists(
|
|
5213
|
+
results.push(await writeIfNotExists({
|
|
5214
|
+
path: sample.relativeFilePath,
|
|
5215
|
+
candidatePaths: sample.candidateRelativeFilePaths,
|
|
5216
|
+
content: sample.content
|
|
5217
|
+
}));
|
|
5220
5218
|
}
|
|
5221
5219
|
return results;
|
|
5222
5220
|
}
|
|
5223
|
-
async function writeIfNotExists(path, content) {
|
|
5224
|
-
if (await require_import.fileExists(
|
|
5221
|
+
async function writeIfNotExists({ path, candidatePaths, content }) {
|
|
5222
|
+
for (const candidatePath of candidatePaths) if (await require_import.fileExists(candidatePath)) return {
|
|
5225
5223
|
created: false,
|
|
5226
|
-
path
|
|
5224
|
+
path: candidatePath
|
|
5227
5225
|
};
|
|
5228
5226
|
await require_import.writeFileContent(path, content);
|
|
5229
5227
|
return {
|
|
@@ -5259,7 +5257,7 @@ async function initCommand(logger) {
|
|
|
5259
5257
|
}
|
|
5260
5258
|
logger.success("rulesync initialized successfully!");
|
|
5261
5259
|
logger.info("Next steps:");
|
|
5262
|
-
logger.info(`1. Edit ${require_import.RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${require_import.RULESYNC_RELATIVE_DIR_PATH}/skills/*/${require_import.SKILL_FILE_NAME}, ${require_import.RULESYNC_MCP_RELATIVE_FILE_PATH}, ${require_import.RULESYNC_HOOKS_RELATIVE_FILE_PATH}
|
|
5260
|
+
logger.info(`1. Edit ${require_import.RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${require_import.RULESYNC_RELATIVE_DIR_PATH}/skills/*/${require_import.SKILL_FILE_NAME}, ${require_import.RULESYNC_MCP_RELATIVE_FILE_PATH}, ${require_import.RULESYNC_HOOKS_RELATIVE_FILE_PATH} and ${require_import.RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}`);
|
|
5263
5261
|
logger.info("2. Run 'rulesync generate' to create configuration files");
|
|
5264
5262
|
}
|
|
5265
5263
|
//#endregion
|
|
@@ -7237,17 +7235,16 @@ async function getHooksFile() {
|
|
|
7237
7235
|
async function putHooksFile({ content }) {
|
|
7238
7236
|
if (content.length > maxHooksSizeBytes) throw new Error(`Hooks file size ${content.length} bytes exceeds maximum ${maxHooksSizeBytes} bytes (1MB) for ${require_import.RULESYNC_HOOKS_RELATIVE_FILE_PATH}`);
|
|
7239
7237
|
try {
|
|
7240
|
-
|
|
7238
|
+
require_import.parseJsonc(content);
|
|
7241
7239
|
} catch (error) {
|
|
7242
|
-
throw new Error(`Invalid
|
|
7240
|
+
throw new Error(`Invalid JSONC format in hooks file (${require_import.RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
7243
7241
|
}
|
|
7244
7242
|
try {
|
|
7245
7243
|
const outputRoot = process.cwd();
|
|
7246
|
-
const
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
const relativeFilePath = paths.relativeFilePath;
|
|
7244
|
+
const { relativeDirPath, relativeFilePath } = await require_import.resolveRulesyncSourceWritePath({
|
|
7245
|
+
outputRoot,
|
|
7246
|
+
paths: require_import.RulesyncHooks.getSettablePaths()
|
|
7247
|
+
});
|
|
7251
7248
|
const fullPath = (0, node_path.join)(outputRoot, relativeDirPath, relativeFilePath);
|
|
7252
7249
|
const rulesyncHooks = new require_import.RulesyncHooks({
|
|
7253
7250
|
outputRoot,
|
|
@@ -7273,9 +7270,8 @@ async function deleteHooksFile() {
|
|
|
7273
7270
|
try {
|
|
7274
7271
|
const outputRoot = process.cwd();
|
|
7275
7272
|
const paths = require_import.RulesyncHooks.getSettablePaths();
|
|
7276
|
-
await require_import.removeFile((0, node_path.join)(outputRoot,
|
|
7277
|
-
|
|
7278
|
-
return { relativePathFromCwd: (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath) };
|
|
7273
|
+
for (const candidate of require_import.getRulesyncSourceCandidates({ paths })) await require_import.removeFile((0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath));
|
|
7274
|
+
return { relativePathFromCwd: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath) };
|
|
7279
7275
|
} catch (error) {
|
|
7280
7276
|
throw new Error(`Failed to delete hooks file (${require_import.RULESYNC_HOOKS_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
7281
7277
|
}
|
|
@@ -7303,7 +7299,7 @@ const hooksTools = {
|
|
|
7303
7299
|
},
|
|
7304
7300
|
putHooksFile: {
|
|
7305
7301
|
name: "putHooksFile",
|
|
7306
|
-
description: "Create or update the hooks configuration file (upsert operation). content parameter is required and must be valid
|
|
7302
|
+
description: "Create or update the hooks configuration file (upsert operation). content parameter is required and must be valid JSONC.",
|
|
7307
7303
|
parameters: hooksToolSchemas.putHooksFile,
|
|
7308
7304
|
execute: async (args) => {
|
|
7309
7305
|
const result = await putHooksFile({ content: args.content });
|
|
@@ -7519,17 +7515,16 @@ async function getMcpFile() {
|
|
|
7519
7515
|
async function putMcpFile({ content }) {
|
|
7520
7516
|
if (content.length > maxMcpSizeBytes) throw new Error(`MCP file size ${content.length} bytes exceeds maximum ${maxMcpSizeBytes} bytes (1MB) for ${require_import.RULESYNC_MCP_RELATIVE_FILE_PATH}`);
|
|
7521
7517
|
try {
|
|
7522
|
-
|
|
7518
|
+
require_import.parseJsonc(content);
|
|
7523
7519
|
} catch (error) {
|
|
7524
|
-
throw new Error(`Invalid
|
|
7520
|
+
throw new Error(`Invalid JSONC format in MCP file (${require_import.RULESYNC_MCP_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
7525
7521
|
}
|
|
7526
7522
|
try {
|
|
7527
7523
|
const outputRoot = process.cwd();
|
|
7528
|
-
const
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
const relativeFilePath = paths.recommended.relativeFilePath;
|
|
7524
|
+
const { relativeDirPath, relativeFilePath } = await require_import.resolveRulesyncSourceWritePath({
|
|
7525
|
+
outputRoot,
|
|
7526
|
+
paths: require_import.RulesyncMcp.getSettablePaths()
|
|
7527
|
+
});
|
|
7533
7528
|
const fullPath = (0, node_path.join)(outputRoot, relativeDirPath, relativeFilePath);
|
|
7534
7529
|
const rulesyncMcp = new require_import.RulesyncMcp({
|
|
7535
7530
|
outputRoot,
|
|
@@ -7555,11 +7550,7 @@ async function deleteMcpFile() {
|
|
|
7555
7550
|
try {
|
|
7556
7551
|
const outputRoot = process.cwd();
|
|
7557
7552
|
const paths = require_import.RulesyncMcp.getSettablePaths();
|
|
7558
|
-
const
|
|
7559
|
-
const legacyPath = (0, node_path.join)(outputRoot, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
|
|
7560
|
-
await require_import.removeFile(recommendedPath);
|
|
7561
|
-
await require_import.removeFile((0, node_path.join)(outputRoot, paths.jsonc.relativeDirPath, paths.jsonc.relativeFilePath));
|
|
7562
|
-
await require_import.removeFile(legacyPath);
|
|
7553
|
+
for (const candidate of require_import.getRulesyncSourceCandidates({ paths })) await require_import.removeFile((0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath));
|
|
7563
7554
|
return { relativePathFromCwd: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath) };
|
|
7564
7555
|
} catch (error) {
|
|
7565
7556
|
throw new Error(`Failed to delete MCP file (${require_import.RULESYNC_MCP_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
@@ -7588,7 +7579,7 @@ const mcpTools = {
|
|
|
7588
7579
|
},
|
|
7589
7580
|
putMcpFile: {
|
|
7590
7581
|
name: "putMcpFile",
|
|
7591
|
-
description: "Create or update the MCP configuration file (upsert operation). content parameter is required and must be valid
|
|
7582
|
+
description: "Create or update the MCP configuration file (upsert operation). content parameter is required and must be valid JSONC.",
|
|
7592
7583
|
parameters: mcpToolSchemas.putMcpFile,
|
|
7593
7584
|
execute: async (args) => {
|
|
7594
7585
|
const result = await putMcpFile({ content: args.content });
|
|
@@ -7628,17 +7619,16 @@ async function getPermissionsFile() {
|
|
|
7628
7619
|
async function putPermissionsFile({ content }) {
|
|
7629
7620
|
if (content.length > maxPermissionsSizeBytes) throw new Error(`Permissions file size ${content.length} bytes exceeds maximum ${maxPermissionsSizeBytes} bytes (1MB) for ${require_import.RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}`);
|
|
7630
7621
|
try {
|
|
7631
|
-
|
|
7622
|
+
require_import.parseJsonc(content);
|
|
7632
7623
|
} catch (error) {
|
|
7633
|
-
throw new Error(`Invalid
|
|
7624
|
+
throw new Error(`Invalid JSONC format in permissions file (${require_import.RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
7634
7625
|
}
|
|
7635
7626
|
try {
|
|
7636
7627
|
const outputRoot = process.cwd();
|
|
7637
|
-
const
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
const relativeFilePath = paths.relativeFilePath;
|
|
7628
|
+
const { relativeDirPath, relativeFilePath } = await require_import.resolveRulesyncSourceWritePath({
|
|
7629
|
+
outputRoot,
|
|
7630
|
+
paths: require_import.RulesyncPermissions.getSettablePaths()
|
|
7631
|
+
});
|
|
7642
7632
|
const fullPath = (0, node_path.join)(outputRoot, relativeDirPath, relativeFilePath);
|
|
7643
7633
|
const rulesyncPermissions = new require_import.RulesyncPermissions({
|
|
7644
7634
|
outputRoot,
|
|
@@ -7664,9 +7654,8 @@ async function deletePermissionsFile() {
|
|
|
7664
7654
|
try {
|
|
7665
7655
|
const outputRoot = process.cwd();
|
|
7666
7656
|
const paths = require_import.RulesyncPermissions.getSettablePaths();
|
|
7667
|
-
await require_import.removeFile((0, node_path.join)(outputRoot,
|
|
7668
|
-
|
|
7669
|
-
return { relativePathFromCwd: (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath) };
|
|
7657
|
+
for (const candidate of require_import.getRulesyncSourceCandidates({ paths })) await require_import.removeFile((0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath));
|
|
7658
|
+
return { relativePathFromCwd: (0, node_path.join)(paths.recommended.relativeDirPath, paths.recommended.relativeFilePath) };
|
|
7670
7659
|
} catch (error) {
|
|
7671
7660
|
throw new Error(`Failed to delete permissions file (${require_import.RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH}): ${require_import.formatError(error)}`, { cause: error });
|
|
7672
7661
|
}
|
|
@@ -7694,7 +7683,7 @@ const permissionsTools = {
|
|
|
7694
7683
|
},
|
|
7695
7684
|
putPermissionsFile: {
|
|
7696
7685
|
name: "putPermissionsFile",
|
|
7697
|
-
description: "Create or update the permissions configuration file (upsert operation). content parameter is required and must be valid
|
|
7686
|
+
description: "Create or update the permissions configuration file (upsert operation). content parameter is required and must be valid JSONC.",
|
|
7698
7687
|
parameters: permissionsToolSchemas.putPermissionsFile,
|
|
7699
7688
|
execute: async (args) => {
|
|
7700
7689
|
const result = await putPermissionsFile({ content: args.content });
|
|
@@ -8991,8 +8980,9 @@ function wrapCommand$1({ name, errorCode, handler, getVersion, loggerFactory = c
|
|
|
8991
8980
|
};
|
|
8992
8981
|
}
|
|
8993
8982
|
//#endregion
|
|
8994
|
-
//#region src/cli/
|
|
8995
|
-
const getVersion = () => "
|
|
8983
|
+
//#region src/cli/program.ts
|
|
8984
|
+
const getVersion = () => "15.0.1";
|
|
8985
|
+
const FEATURES_HELP = `${require_import.ALL_FEATURES.join(",")}; ignore is deprecated, use permissions`;
|
|
8996
8986
|
function wrapCommand(name, errorCode, handler) {
|
|
8997
8987
|
return wrapCommand$1({
|
|
8998
8988
|
name,
|
|
@@ -9001,14 +8991,14 @@ function wrapCommand(name, errorCode, handler) {
|
|
|
9001
8991
|
getVersion
|
|
9002
8992
|
});
|
|
9003
8993
|
}
|
|
9004
|
-
|
|
8994
|
+
function createProgram() {
|
|
9005
8995
|
const program = new commander.Command();
|
|
9006
8996
|
const version = getVersion();
|
|
9007
8997
|
program.name("rulesync").description("Unified AI rules management CLI tool").version(version, "-v, --version", "Show version").option("-j, --json", "Output results as JSON");
|
|
9008
8998
|
program.command("init").description("Initialize rulesync in current directory").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("init", "INIT_FAILED", async (logger) => {
|
|
9009
8999
|
await initCommand(logger);
|
|
9010
9000
|
}));
|
|
9011
|
-
program.command("gitignore").description("Add generated files to .gitignore").option("-t, --targets <tools>", "Comma-separated list of tools to include (e.g., 'claudecode,copilot' or '*' for all)", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to include (${
|
|
9001
|
+
program.command("gitignore").description("Add generated files to .gitignore").option("-t, --targets <tools>", "Comma-separated list of tools to include (e.g., 'claudecode,copilot' or '*' for all)", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to include (${FEATURES_HELP}) or '*' for all`, parseCommaSeparatedList).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("gitignore", "GITIGNORE_FAILED", async (logger, options) => {
|
|
9012
9002
|
const cliTargets = options.targets;
|
|
9013
9003
|
const cliFeatures = options.features;
|
|
9014
9004
|
const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
|
|
@@ -9019,7 +9009,7 @@ const main = async () => {
|
|
|
9019
9009
|
silent: options.silent
|
|
9020
9010
|
});
|
|
9021
9011
|
}));
|
|
9022
|
-
program.command("add <source>").description("Add a Rulesync feature file or install a declarative rule or skill source").option("--name <name>", "Name for a rule, command, subagent, skill, or check scaffold").option("-f, --force", "Overwrite an existing scaffold file without prompting").option("--skills <skills>", "Comma-separated skill names to install", parseCommaSeparatedList).option("--rules <rules>", "Comma-separated rule names to install", parseCommaSeparatedList).option("--transport <transport>", "Source transport: github, git, or npm").option("-r, --ref <ref>", "Git ref, npm version, or npm dist-tag").option("-p, --path <path>", "Skills path within the source").option("--rules-path <path>", "Rules path within the source").option("--registry <url>", "npm-compatible registry URL").option("--token-env <name>", "Environment variable containing the npm registry token").option("--token <token>", "GitHub token for private repositories").option("-c, --config <path>", "Path to configuration file").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("add", "ADD_FAILED", async (logger, options, _globalOpts, positionalArgs) => {
|
|
9012
|
+
program.command("add <source>").description("Add a Rulesync feature file (ignore is deprecated; use permissions) or install a declarative rule or skill source").option("--name <name>", "Name for a rule, command, subagent, skill, or check scaffold").option("-f, --force", "Overwrite an existing scaffold file without prompting").option("--skills <skills>", "Comma-separated skill names to install", parseCommaSeparatedList).option("--rules <rules>", "Comma-separated rule names to install", parseCommaSeparatedList).option("--transport <transport>", "Source transport: github, git, or npm").option("-r, --ref <ref>", "Git ref, npm version, or npm dist-tag").option("-p, --path <path>", "Skills path within the source").option("--rules-path <path>", "Rules path within the source").option("--registry <url>", "npm-compatible registry URL").option("--token-env <name>", "Environment variable containing the npm registry token").option("--token <token>", "GitHub token for private repositories").option("-c, --config <path>", "Path to configuration file").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("add", "ADD_FAILED", async (logger, options, _globalOpts, positionalArgs) => {
|
|
9023
9013
|
const source = positionalArgs[0];
|
|
9024
9014
|
const addOptions = options;
|
|
9025
9015
|
await addCommand(logger, {
|
|
@@ -9028,17 +9018,21 @@ const main = async () => {
|
|
|
9028
9018
|
configPath: addOptions.config
|
|
9029
9019
|
});
|
|
9030
9020
|
}));
|
|
9031
|
-
program.command("fetch <source>").description("Fetch files from a Git repository (GitHub/GitLab)").option("-t, --target <target>", "Target format to interpret files as (e.g., 'rulesync', 'claudecode'). Default: rulesync").option("-f, --features <features>", `Comma-separated list of features to fetch (${
|
|
9021
|
+
program.command("fetch <source>").description("Fetch files from a Git repository (GitHub/GitLab)").option("-t, --target <target>", "Target format to interpret files as (e.g., 'rulesync', 'claudecode'). Default: rulesync").option("-f, --features <features>", `Comma-separated list of features to fetch (${FEATURES_HELP}) or '*' for all. Default: skills`, parseCommaSeparatedList).option("-r, --ref <ref>", "Branch, tag, or commit SHA to fetch from").option("-p, --path <path>", "Subdirectory path within the repository").option("-o, --output <dir>", "Output directory (default: .rulesync)").option("-c, --conflict <strategy>", "Conflict resolution strategy: skip, overwrite (default: overwrite)").option("--token <token>", "Git provider token for private repositories").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("fetch", "FETCH_FAILED", async (logger, options, _globalOpts, positionalArgs) => {
|
|
9032
9022
|
const source = positionalArgs[0];
|
|
9033
9023
|
await fetchCommand(logger, {
|
|
9034
9024
|
...options,
|
|
9035
9025
|
source
|
|
9036
9026
|
});
|
|
9037
9027
|
}));
|
|
9038
|
-
program.command("import").description("Import configurations from AI tools to rulesync format").option("-t, --targets <tool>", "Tool to import from (e.g., 'copilot', 'cursor', 'cline')", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to import (${
|
|
9039
|
-
|
|
9028
|
+
program.command("import").description("Import configurations from AI tools to rulesync format").option("-t, --targets <tool>", "Tool to import from (e.g., 'copilot', 'cursor', 'cline')", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to import (${FEATURES_HELP}) or '*' for all`, parseCommaSeparatedList).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").option("-g, --global", "Import for global(user scope) configuration files").option("-o, --output-root <path>", "Root directory containing the tool configuration to import").action(wrapCommand("import", "IMPORT_FAILED", async (logger, options) => {
|
|
9029
|
+
const { outputRoot, ...importOptions } = options;
|
|
9030
|
+
await importCommand(logger, {
|
|
9031
|
+
...importOptions,
|
|
9032
|
+
outputRoots: outputRoot ? [outputRoot] : void 0
|
|
9033
|
+
});
|
|
9040
9034
|
}));
|
|
9041
|
-
program.command("convert").description("Convert configurations from one AI tool to other AI tools without writing .rulesync/ files").requiredOption("--from <tool>", "Source tool to convert from (e.g., 'cursor', 'claudecode')").requiredOption("--to <tools>", "Comma-separated list of destination tools (e.g., 'copilot,claudecode')", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to convert (${
|
|
9035
|
+
program.command("convert").description("Convert configurations from one AI tool to other AI tools without writing .rulesync/ files").requiredOption("--from <tool>", "Source tool to convert from (e.g., 'cursor', 'claudecode')").requiredOption("--to <tools>", "Comma-separated list of destination tools (e.g., 'copilot,claudecode')", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to convert (${FEATURES_HELP}) or '*' for all`, parseCommaSeparatedList).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").option("-g, --global", "Convert for global(user scope) configuration files").option("--dry-run", "Dry run: show changes without writing files").action(wrapCommand("convert", "CONVERT_FAILED", async (logger, options) => {
|
|
9042
9036
|
await convertCommand(logger, options);
|
|
9043
9037
|
}));
|
|
9044
9038
|
program.command("mcp").description("Start MCP server for rulesync").action(wrapCommand("mcp", "MCP_FAILED", async (logger, _options) => {
|
|
@@ -9056,20 +9050,25 @@ const main = async () => {
|
|
|
9056
9050
|
silent: options.silent
|
|
9057
9051
|
});
|
|
9058
9052
|
}));
|
|
9059
|
-
program.command("generate").description("Generate configuration files for AI tools").option("-t, --targets <tools>", "Comma-separated list of tools to generate for (e.g., 'copilot,cursor,cline' or '*' for all)", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to generate (${
|
|
9053
|
+
program.command("generate").description("Generate configuration files for AI tools").option("-t, --targets <tools>", "Comma-separated list of tools to generate for (e.g., 'copilot,cursor,cline' or '*' for all)", parseCommaSeparatedList).option("-f, --features <features>", `Comma-separated list of features to generate (${FEATURES_HELP}) or '*' for all`, parseCommaSeparatedList).option("--delete", "Delete all existing files in output directories before generating").option("-o, --output-roots <paths>", "Output root directories to generate files into (comma-separated for multiple paths)", parseCommaSeparatedList).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").option("-c, --config <path>", "Path to configuration file").option("-g, --global", "Generate for global(user scope) configuration files").option("--simulate-commands", "Generate simulated commands. This feature is only available for copilot, cursor and codexcli.").option("--simulate-subagents", "Generate simulated subagents. This feature is only available for copilot and codexcli.").option("--simulate-skills", "Generate simulated skills. This feature is only available for copilot, cursor and codexcli.").option("--input-root <path>", "Path to the directory containing .rulesync/ (parent of .rulesync/)").option("--dry-run", "Dry run: show changes without writing files").option("--check", "Check if files are up to date (exits with code 1 if changes needed)").action(wrapCommand("generate", "GENERATION_FAILED", async (logger, options) => {
|
|
9060
9054
|
await generateCommand(logger, options);
|
|
9061
9055
|
}));
|
|
9062
9056
|
program.command("update").description("Update rulesync to the latest version").option("--check", "Check for updates without installing").option("--force", "Force update even if already at latest version").option("--token <token>", "GitHub token for API access").option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(wrapCommand("update", "UPDATE_FAILED", async (logger, options) => {
|
|
9063
9057
|
await updateCommand(logger, version, options);
|
|
9064
9058
|
}));
|
|
9065
|
-
program
|
|
9066
|
-
}
|
|
9059
|
+
return program;
|
|
9060
|
+
}
|
|
9067
9061
|
function parseInstallMode(raw) {
|
|
9068
9062
|
if (raw === void 0) return void 0;
|
|
9069
9063
|
const match = INSTALL_MODES.find((m) => m === raw);
|
|
9070
9064
|
if (!match) throw new Error(`Invalid --mode value "${raw}". Expected one of: ${INSTALL_MODES.join(", ")}.`);
|
|
9071
9065
|
return match;
|
|
9072
9066
|
}
|
|
9067
|
+
//#endregion
|
|
9068
|
+
//#region src/cli/index.ts
|
|
9069
|
+
async function main() {
|
|
9070
|
+
createProgram().parse();
|
|
9071
|
+
}
|
|
9073
9072
|
main().catch((error) => {
|
|
9074
9073
|
console.error(require_import.formatError(error));
|
|
9075
9074
|
process.exit(1);
|