rulesync 7.18.2 → 7.20.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.
@@ -15,8 +15,31 @@ function formatError(error) {
15
15
  return String(error);
16
16
  }
17
17
 
18
- // src/utils/logger.ts
19
- import { consola } from "consola";
18
+ // src/types/json-output.ts
19
+ var ErrorCodes = {
20
+ CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
21
+ RULESYNC_DIR_NOT_FOUND: "RULESYNC_DIR_NOT_FOUND",
22
+ INVALID_TARGET: "INVALID_TARGET",
23
+ FETCH_FAILED: "FETCH_FAILED",
24
+ WRITE_FAILED: "WRITE_FAILED",
25
+ VALIDATION_FAILED: "VALIDATION_FAILED",
26
+ GENERATION_FAILED: "GENERATION_FAILED",
27
+ IMPORT_FAILED: "IMPORT_FAILED",
28
+ INSTALL_FAILED: "INSTALL_FAILED",
29
+ UPDATE_FAILED: "UPDATE_FAILED",
30
+ GITIGNORE_FAILED: "GITIGNORE_FAILED",
31
+ INIT_FAILED: "INIT_FAILED",
32
+ MCP_FAILED: "MCP_FAILED",
33
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
34
+ };
35
+ var CLIError = class extends Error {
36
+ constructor(message, code = ErrorCodes.UNKNOWN_ERROR, exitCode = 1) {
37
+ super(message);
38
+ this.code = code;
39
+ this.exitCode = exitCode;
40
+ this.name = "CLIError";
41
+ }
42
+ };
20
43
 
21
44
  // src/utils/vitest.ts
22
45
  function isEnvTest() {
@@ -24,60 +47,135 @@ function isEnvTest() {
24
47
  }
25
48
 
26
49
  // src/utils/logger.ts
27
- var Logger = class {
50
+ var BaseLogger = class {
28
51
  _verbose = false;
29
52
  _silent = false;
30
- console = consola.withDefaults({
31
- tag: "rulesync"
32
- });
33
- /**
34
- * Configure logger with verbose and silent mode settings.
35
- * Handles conflicting flags where silent takes precedence.
36
- * @param verbose - Enable verbose logging
37
- * @param silent - Enable silent mode (suppresses all output except errors)
38
- */
53
+ get verbose() {
54
+ return this._verbose;
55
+ }
56
+ get silent() {
57
+ return this._silent;
58
+ }
39
59
  configure({ verbose, silent }) {
40
60
  if (verbose && silent) {
41
61
  this._silent = false;
42
- this.warn("Both --verbose and --silent specified; --silent takes precedence");
62
+ if (!isEnvTest()) {
63
+ console.warn("Both --verbose and --silent specified; --silent takes precedence");
64
+ }
43
65
  }
44
66
  this._silent = silent;
45
67
  this._verbose = verbose && !silent;
46
68
  }
47
- get verbose() {
48
- return this._verbose;
69
+ };
70
+ var ConsoleLogger = class extends BaseLogger {
71
+ isSuppressed() {
72
+ return isEnvTest() || this._silent;
49
73
  }
50
- get silent() {
51
- return this._silent;
74
+ get jsonMode() {
75
+ return false;
76
+ }
77
+ captureData(_key, _value) {
78
+ }
79
+ getJsonData() {
80
+ return {};
81
+ }
82
+ outputJson(_success, _error) {
52
83
  }
53
84
  info(message, ...args) {
54
- if (isEnvTest() || this._silent) return;
55
- this.console.info(message, ...args);
85
+ if (this.isSuppressed()) return;
86
+ console.log(message, ...args);
56
87
  }
57
- // Success (always shown unless silent)
58
88
  success(message, ...args) {
59
- if (isEnvTest() || this._silent) return;
60
- this.console.success(message, ...args);
89
+ if (this.isSuppressed()) return;
90
+ console.log(message, ...args);
61
91
  }
62
- // Warning (always shown unless silent)
63
92
  warn(message, ...args) {
64
- if (isEnvTest() || this._silent) return;
65
- this.console.warn(message, ...args);
93
+ if (this.isSuppressed()) return;
94
+ console.warn(message, ...args);
66
95
  }
67
- // Error (always shown, even in silent mode)
68
- error(message, ...args) {
96
+ error(message, _code, ...args) {
69
97
  if (isEnvTest()) return;
70
- this.console.error(message, ...args);
98
+ const errorMessage = message instanceof Error ? message.message : message;
99
+ console.error(errorMessage, ...args);
71
100
  }
72
- // Debug level (shown only in verbose mode)
73
101
  debug(message, ...args) {
74
- if (isEnvTest() || this._silent) return;
102
+ if (this.isSuppressed()) return;
75
103
  if (this._verbose) {
76
- this.console.info(message, ...args);
104
+ console.log(message, ...args);
77
105
  }
78
106
  }
79
107
  };
80
- var logger = new Logger();
108
+ var JsonLogger = class extends BaseLogger {
109
+ _jsonOutputDone = false;
110
+ _jsonData = {};
111
+ _commandName;
112
+ _version;
113
+ constructor({ command, version }) {
114
+ super();
115
+ this._commandName = command;
116
+ this._version = version;
117
+ }
118
+ get jsonMode() {
119
+ return true;
120
+ }
121
+ captureData(key, value) {
122
+ this._jsonData[key] = value;
123
+ }
124
+ getJsonData() {
125
+ return { ...this._jsonData };
126
+ }
127
+ outputJson(success, error) {
128
+ if (this._jsonOutputDone) return;
129
+ this._jsonOutputDone = true;
130
+ const output = {
131
+ success,
132
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
133
+ command: this._commandName,
134
+ version: this._version
135
+ };
136
+ if (success) {
137
+ output.data = this._jsonData;
138
+ } else if (error) {
139
+ output.error = {
140
+ code: error.code,
141
+ message: error.message
142
+ };
143
+ if (error.details) {
144
+ output.error.details = error.details;
145
+ }
146
+ if (error.stack) {
147
+ output.error.stack = error.stack;
148
+ }
149
+ }
150
+ const jsonStr = JSON.stringify(output, null, 2);
151
+ if (success) {
152
+ console.log(jsonStr);
153
+ } else {
154
+ console.error(jsonStr);
155
+ }
156
+ }
157
+ info(_message, ..._args) {
158
+ }
159
+ success(_message, ..._args) {
160
+ }
161
+ warn(_message, ..._args) {
162
+ }
163
+ error(message, code, ..._args) {
164
+ if (isEnvTest()) return;
165
+ const errorMessage = message instanceof Error ? message.message : message;
166
+ const errorInfo = {
167
+ code: code || ErrorCodes.UNKNOWN_ERROR,
168
+ message: errorMessage
169
+ };
170
+ if (this._verbose && message instanceof Error && message.stack) {
171
+ errorInfo.stack = message.stack;
172
+ }
173
+ this.outputJson(false, errorInfo);
174
+ }
175
+ debug(_message, ..._args) {
176
+ }
177
+ };
178
+ var logger = new ConsoleLogger();
81
179
 
82
180
  // src/types/features.ts
83
181
  import { z } from "zod/mini";
@@ -3304,7 +3402,9 @@ var CLAUDE_HOOK_EVENTS = [
3304
3402
  "preCompact",
3305
3403
  "permissionRequest",
3306
3404
  "notification",
3307
- "setup"
3405
+ "setup",
3406
+ "worktreeCreate",
3407
+ "worktreeRemove"
3308
3408
  ];
3309
3409
  var OPENCODE_HOOK_EVENTS = [
3310
3410
  "sessionStart",
@@ -3371,7 +3471,9 @@ var CANONICAL_TO_CLAUDE_EVENT_NAMES = {
3371
3471
  preCompact: "PreCompact",
3372
3472
  permissionRequest: "PermissionRequest",
3373
3473
  notification: "Notification",
3374
- setup: "Setup"
3474
+ setup: "Setup",
3475
+ worktreeCreate: "WorktreeCreate",
3476
+ worktreeRemove: "WorktreeRemove"
3375
3477
  };
3376
3478
  var CLAUDE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(
3377
3479
  Object.entries(CANONICAL_TO_CLAUDE_EVENT_NAMES).map(([k, v]) => [v, k])
@@ -3497,7 +3599,13 @@ function canonicalToToolHooks({
3497
3599
  else byMatcher.set(key, [def]);
3498
3600
  }
3499
3601
  const entries = [];
3602
+ const isNoMatcherEvent = converterConfig.noMatcherEvents?.has(eventName) ?? false;
3500
3603
  for (const [matcherKey, defs] of byMatcher) {
3604
+ if (isNoMatcherEvent && matcherKey) {
3605
+ logger.warn(
3606
+ `matcher "${matcherKey}" on "${eventName}" hook will be ignored \u2014 this event does not support matchers`
3607
+ );
3608
+ }
3501
3609
  const hooks = defs.map((def) => {
3502
3610
  const commandText = def.command;
3503
3611
  const trimmedCommand = typeof commandText === "string" ? commandText.trimStart() : void 0;
@@ -3510,7 +3618,8 @@ function canonicalToToolHooks({
3510
3618
  ...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt }
3511
3619
  };
3512
3620
  });
3513
- entries.push(matcherKey ? { matcher: matcherKey, hooks } : { hooks });
3621
+ const includeMatcher = matcherKey && !isNoMatcherEvent;
3622
+ entries.push(includeMatcher ? { matcher: matcherKey, hooks } : { hooks });
3514
3623
  }
3515
3624
  result[toolEventName] = entries;
3516
3625
  }
@@ -3648,12 +3757,14 @@ var ToolHooks = class extends ToolFile {
3648
3757
  };
3649
3758
 
3650
3759
  // src/features/hooks/claudecode-hooks.ts
3760
+ var CLAUDE_NO_MATCHER_EVENTS = /* @__PURE__ */ new Set(["worktreeCreate", "worktreeRemove"]);
3651
3761
  var CLAUDE_CONVERTER_CONFIG = {
3652
3762
  supportedEvents: CLAUDE_HOOK_EVENTS,
3653
3763
  canonicalToToolEventNames: CANONICAL_TO_CLAUDE_EVENT_NAMES,
3654
3764
  toolToCanonicalEventNames: CLAUDE_TO_CANONICAL_EVENT_NAMES,
3655
3765
  projectDirVar: "$CLAUDE_PROJECT_DIR",
3656
- prefixDotRelativeCommandsOnly: true
3766
+ prefixDotRelativeCommandsOnly: true,
3767
+ noMatcherEvents: CLAUDE_NO_MATCHER_EVENTS
3657
3768
  };
3658
3769
  var ClaudecodeHooks = class _ClaudecodeHooks extends ToolHooks {
3659
3770
  constructor(params) {
@@ -17154,6 +17265,10 @@ export {
17154
17265
  MAX_FILE_SIZE,
17155
17266
  FETCH_CONCURRENCY_LIMIT,
17156
17267
  formatError,
17268
+ ErrorCodes,
17269
+ CLIError,
17270
+ ConsoleLogger,
17271
+ JsonLogger,
17157
17272
  logger,
17158
17273
  ensureDir,
17159
17274
  checkPathTraversal,
@@ -17172,6 +17287,7 @@ export {
17172
17287
  ALL_FEATURES,
17173
17288
  ALL_FEATURES_WITH_WILDCARD,
17174
17289
  ALL_TOOL_TARGETS,
17290
+ ALL_TOOL_TARGETS_WITH_WILDCARD,
17175
17291
  findControlCharacter,
17176
17292
  ConfigResolver,
17177
17293
  stringifyFrontmatter,