rulekeeper 0.1.3 → 0.1.5

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 CHANGED
@@ -8,7 +8,7 @@ A cross-platform CLI tool for syncing and managing [Claude Code](https://docs.an
8
8
 
9
9
  RuleKeeper helps teams and multi-project users maintain consistent Claude Code configurations by:
10
10
 
11
- - Syncing `.claude/` directory files from a central source (local folder or git repository)
11
+ - Syncing `.claude/rules/` directory files from a central source (local folder or git repository)
12
12
  - Tracking rule states: synced, outdated, diverged, or detached
13
13
  - Supporting selective rule installation per project
14
14
  - Handling conflicts when local changes exist
@@ -135,7 +135,7 @@ rk add -a # Add all available rules
135
135
  | `-a, --all` | Add all available rules from source |
136
136
 
137
137
  **Behavior:**
138
- - Creates `.claude/` directory if it doesn't exist
138
+ - Creates `.claude/rules/` directory if it doesn't exist
139
139
  - Rule names are case-insensitive (`Coding-Style` matches `coding-style.md`)
140
140
  - Prompts for confirmation if a file already exists with local changes
141
141
  - Options when conflict detected: overwrite, skip, or detach
@@ -336,9 +336,9 @@ rk doctor
336
336
  | `diverged` | Local changes exist that differ from source | Prompted to overwrite or detach |
337
337
  | `detached` | Intentionally diverged, excluded from updates | Ignored by `rk pull` unless `--include-detached` |
338
338
 
339
- ## Handling Existing `.claude` Directories
339
+ ## Handling Existing `.claude/rules` Directories
340
340
 
341
- When adding rules to a project that already has a `.claude` directory with existing files:
341
+ When adding rules to a project that already has a `.claude/rules` directory with existing files:
342
342
 
343
343
  1. **New rules** - Files that don't exist locally are copied from source
344
344
  2. **Existing untracked files** - You're prompted to: overwrite, skip, or detach
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import updateNotifier from "update-notifier";
7
7
 
8
8
  // src/commands/init.ts
9
9
  import { join as join5 } from "path";
10
+ import pc4 from "picocolors";
10
11
 
11
12
  // src/lib/config.ts
12
13
  import { parse, stringify } from "yaml";
@@ -23,7 +24,7 @@ function getConfigPath() {
23
24
  return join(getConfigDir(), "config.yaml");
24
25
  }
25
26
  function getClaudeDir(projectPath = process.cwd()) {
26
- return join(projectPath, ".claude");
27
+ return join(projectPath, ".claude", "rules");
27
28
  }
28
29
  function getRulekeeperDir(projectPath = process.cwd()) {
29
30
  return join(projectPath, ".rulekeeper");
@@ -45,6 +46,11 @@ function expandTilde(path) {
45
46
  import { existsSync, mkdirSync } from "fs";
46
47
  import { readFile, writeFile, copyFile as fsCopyFile, readdir, unlink, rm } from "fs/promises";
47
48
  import { dirname, basename } from "path";
49
+ var IGNORED_FILES = ["readme.md"];
50
+ function isIgnoredRule(ruleName) {
51
+ const filename = getRuleFilename(ruleName);
52
+ return IGNORED_FILES.includes(filename.toLowerCase());
53
+ }
48
54
  function ensureDir(dirPath) {
49
55
  if (!existsSync(dirPath)) {
50
56
  mkdirSync(dirPath, { recursive: true });
@@ -223,7 +229,6 @@ async function hashFile(filePath) {
223
229
  }
224
230
 
225
231
  // src/lib/source.ts
226
- var IGNORED_FILES = ["readme.md"];
227
232
  async function getAvailableRules(config) {
228
233
  const sourcePath = config.source.path;
229
234
  if (!fileExists(sourcePath)) {
@@ -406,7 +411,7 @@ var messages = {
406
411
  // General
407
412
  notConfigured: `RuleKeeper is not configured. Run ${formatCommand("rk init")} first.`,
408
413
  noManifest: `No RuleKeeper manifest found. Run ${formatCommand("rk add")} first.`,
409
- noClaudeDir: `No .claude/ directory found. Are you in a project root?`,
414
+ noClaudeDir: `No .claude/rules/ directory found. Are you in a project root?`,
410
415
  // Init
411
416
  initWelcome: "Welcome to RuleKeeper!",
412
417
  initSuccess: "RuleKeeper is now configured.",
@@ -417,7 +422,7 @@ var messages = {
417
422
  sourceUpdated: (path) => `Source updated to: ${formatPath(path)}`,
418
423
  // Add
419
424
  addSuccess: (count) => `Added ${count} rule${count !== 1 ? "s" : ""}.`,
420
- addConflict: (files) => `The following files already exist in .claude/:
425
+ addConflict: (files) => `The following files already exist in .claude/rules/:
421
426
  ${files.map((f) => ` - ${f}`).join("\n")}`,
422
427
  addNoRules: "No rules specified. Use --all to add all available rules.",
423
428
  ruleNotFound: (name) => `Rule '${name}' not found in source.`,
@@ -704,6 +709,12 @@ async function init(options = {}) {
704
709
  });
705
710
  await saveConfig(config);
706
711
  outro2(messages.initSuccess);
712
+ log2.info("");
713
+ log2.info("Next steps:");
714
+ log2.info(` \u2022 Navigate to a project: ${pc4.dim("cd my-project")}`);
715
+ log2.info(` \u2022 Add all rules: ${pc4.cyan("rk add -a")}`);
716
+ log2.info(` \u2022 Or add specific rule: ${pc4.cyan("rk add <rule-name>")}`);
717
+ log2.info(` \u2022 List available rules: ${pc4.cyan("rk list")}`);
707
718
  }
708
719
 
709
720
  // src/commands/add.ts
@@ -912,6 +923,9 @@ async function status() {
912
923
  const claudeDir = getClaudeDir();
913
924
  let needsAttention = 0;
914
925
  for (const ruleName of ruleNames.sort()) {
926
+ if (isIgnoredRule(ruleName)) {
927
+ continue;
928
+ }
915
929
  const entry = manifest.rules[ruleName];
916
930
  const filename = getRuleFilename(ruleName);
917
931
  const localPath = join8(claudeDir, filename);
@@ -1178,6 +1192,9 @@ async function pull(rules, options = {}) {
1178
1192
  const claudeDir = getClaudeDir();
1179
1193
  const isSingleRule = rules.length === 1;
1180
1194
  for (const ruleName of rulesToProcess) {
1195
+ if (isIgnoredRule(ruleName)) {
1196
+ continue;
1197
+ }
1181
1198
  const entry = manifest.rules[ruleName];
1182
1199
  if (!entry) {
1183
1200
  log2.warn(`Rule '${ruleName}' not found in manifest`);
@@ -1345,7 +1362,7 @@ async function pullRule(ruleName, entry, sourcePath, localPath, manifest, option
1345
1362
  }
1346
1363
 
1347
1364
  // src/commands/list.ts
1348
- import pc4 from "picocolors";
1365
+ import pc5 from "picocolors";
1349
1366
  async function list(options = {}) {
1350
1367
  const config = await loadConfig();
1351
1368
  if (!config) {
@@ -1374,7 +1391,7 @@ async function list(options = {}) {
1374
1391
  console.log("");
1375
1392
  for (const rule of installedRules.sort()) {
1376
1393
  const entry = manifest.rules[rule];
1377
- const statusHint = entry.status !== "synced" ? pc4.dim(` (${entry.status})`) : "";
1394
+ const statusHint = entry.status !== "synced" ? pc5.dim(` (${entry.status})`) : "";
1378
1395
  console.log(` ${rule}.md${statusHint}`);
1379
1396
  }
1380
1397
  } else {
@@ -1388,12 +1405,12 @@ async function list(options = {}) {
1388
1405
  console.log("");
1389
1406
  for (const rule of availableRules.sort((a, b) => a.name.localeCompare(b.name))) {
1390
1407
  const installed = installedRules.includes(rule.name);
1391
- const icon = installed ? pc4.green("\u2713") : pc4.dim("\u25CB");
1392
- const hint = installed ? pc4.dim(" (installed)") : "";
1408
+ const icon = installed ? pc5.green("\u2713") : pc5.dim("\u25CB");
1409
+ const hint = installed ? pc5.dim(" (installed)") : "";
1393
1410
  console.log(` ${icon} ${rule.name}.md${hint}`);
1394
1411
  }
1395
1412
  console.log("");
1396
- console.log(pc4.dim(`Source: ${config.source.path}`));
1413
+ console.log(pc5.dim(`Source: ${config.source.path}`));
1397
1414
  }
1398
1415
  console.log("");
1399
1416
  }
@@ -1645,7 +1662,7 @@ async function sourceConfig(options) {
1645
1662
 
1646
1663
  // src/commands/doctor.ts
1647
1664
  import { join as join13 } from "path";
1648
- import pc5 from "picocolors";
1665
+ import pc6 from "picocolors";
1649
1666
  async function doctor() {
1650
1667
  console.log("");
1651
1668
  console.log(formatHeader("RuleKeeper Diagnostics"));
@@ -1662,7 +1679,7 @@ async function doctor() {
1662
1679
  results.push({
1663
1680
  name: "Global config",
1664
1681
  status: "fail",
1665
- message: `Not found. Run ${pc5.cyan("rk init")} to configure.`
1682
+ message: `Not found. Run ${pc6.cyan("rk init")} to configure.`
1666
1683
  });
1667
1684
  }
1668
1685
  const config = await loadConfig();
@@ -1769,7 +1786,7 @@ async function doctor() {
1769
1786
  results.push({
1770
1787
  name: "RuleKeeper manifest",
1771
1788
  status: "warn",
1772
- message: `No manifest. Run ${pc5.cyan("rk add")} to start tracking rules.`
1789
+ message: `No manifest. Run ${pc6.cyan("rk add")} to start tracking rules.`
1773
1790
  });
1774
1791
  }
1775
1792
  let passCount = 0;
@@ -1781,17 +1798,17 @@ async function doctor() {
1781
1798
  switch (result.status) {
1782
1799
  case "pass":
1783
1800
  icon = "\u2713";
1784
- color = pc5.green;
1801
+ color = pc6.green;
1785
1802
  passCount++;
1786
1803
  break;
1787
1804
  case "warn":
1788
1805
  icon = "\u26A0";
1789
- color = pc5.yellow;
1806
+ color = pc6.yellow;
1790
1807
  warnCount++;
1791
1808
  break;
1792
1809
  case "fail":
1793
1810
  icon = "\u2717";
1794
- color = pc5.red;
1811
+ color = pc6.red;
1795
1812
  failCount++;
1796
1813
  break;
1797
1814
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/config.ts","../src/lib/paths.ts","../src/lib/files.ts","../src/types/config.ts","../src/types/manifest.ts","../src/lib/manifest.ts","../src/lib/source.ts","../src/lib/hash.ts","../src/lib/git.ts","../src/lib/platform.ts","../src/ui/format.ts","../src/ui/messages.ts","../src/ui/prompts.ts","../src/commands/add.ts","../src/commands/remove.ts","../src/commands/status.ts","../src/commands/pull.ts","../src/commands/diff.ts","../src/commands/list.ts","../src/commands/detach.ts","../src/commands/attach.ts","../src/commands/source.ts","../src/commands/doctor.ts"],"sourcesContent":["import { createRequire } from 'module'\nimport { Command } from 'commander'\nimport updateNotifier from 'update-notifier'\nimport {\n init,\n add,\n remove,\n status,\n pull,\n diff,\n list,\n detach,\n attach,\n sourceShow,\n sourceSet,\n sourcePull,\n sourceConfig,\n doctor\n} from './commands/index.js'\nimport type { PullFrequency } from './types/index.js'\n\nconst require = createRequire(import.meta.url)\nconst packageJson = require('../package.json')\n\n// Check for updates (runs in background, shows message at exit if update available)\nupdateNotifier({ pkg: packageJson }).notify({ isGlobal: true })\n\nconst program = new Command()\n\nprogram\n .name('rulekeeper')\n .description('Sync and manage Claude Code rules across projects')\n .version(packageJson.version)\n\nprogram\n .command('init')\n .description('Interactive global setup')\n .option('-f, --force', 'Overwrite existing configuration')\n .action(async (options) => {\n await init({ force: options.force })\n })\n\nprogram\n .command('add [rules...]')\n .description('Add rules to current project')\n .option('-a, --all', 'Add all available rules')\n .action(async (rules, options) => {\n await add(rules, { all: options.all })\n })\n\nprogram\n .command('remove <rules...>')\n .description('Remove rules from project')\n .option('-k, --keep-file', 'Keep the local file, only remove from manifest')\n .action(async (rules, options) => {\n await remove(rules, { keepFile: options.keepFile })\n })\n\nprogram\n .command('status')\n .description('Show rule states in current project')\n .action(async () => {\n await status()\n })\n\nprogram\n .command('pull [rules...]')\n .description('Update rules from source')\n .option('-f, --force', 'Overwrite diverged rules without prompting')\n .option('--include-detached', 'Include detached rules')\n .action(async (rules, options) => {\n await pull(rules, {\n force: options.force,\n includeDetached: options.includeDetached\n })\n })\n\nprogram\n .command('diff [rule]')\n .description('Show differences between local and source')\n .option('-a, --all', 'Show diff for all diverged rules')\n .action(async (rule, options) => {\n const rules = rule ? [rule] : []\n await diff(rules, { all: options.all })\n })\n\nprogram\n .command('list')\n .description('List available rules')\n .option('-i, --installed', 'Show only installed rules')\n .action(async (options) => {\n await list({ installed: options.installed })\n })\n\nprogram\n .command('detach <rule>')\n .description('Mark rule as intentionally diverged')\n .action(async (rule) => {\n await detach(rule)\n })\n\nprogram\n .command('attach <rule>')\n .description('Resume tracking a detached rule')\n .action(async (rule) => {\n await attach(rule)\n })\n\n// Source subcommands\nconst sourceCmd = program\n .command('source')\n .description('Manage source configuration')\n\nsourceCmd\n .command('show')\n .description('Show current source configuration')\n .action(async () => {\n await sourceShow()\n })\n\nsourceCmd\n .command('set <path-or-url>')\n .description('Change source location')\n .action(async (pathOrUrl) => {\n await sourceSet(pathOrUrl)\n })\n\nsourceCmd\n .command('pull')\n .description('Manually pull from git remote')\n .action(async () => {\n await sourcePull()\n })\n\nsourceCmd\n .command('config')\n .description('View or update pull settings')\n .option('--auto-pull <boolean>', 'Enable or disable auto-pull (on/off)')\n .option('--frequency <freq>', 'Set pull frequency (always, daily, weekly)')\n .action(async (options) => {\n let autoPull: boolean | undefined\n if (options.autoPull !== undefined) {\n const val = options.autoPull.toLowerCase()\n if (val === 'on' || val === 'true' || val === '1') {\n autoPull = true\n } else if (val === 'off' || val === 'false' || val === '0') {\n autoPull = false\n } else {\n console.error('Invalid value for --auto-pull. Use: on, off, true, false')\n process.exit(1)\n }\n }\n\n let frequency: PullFrequency | undefined\n if (options.frequency !== undefined) {\n const val = options.frequency.toLowerCase()\n if (val === 'always' || val === 'daily' || val === 'weekly') {\n frequency = val as PullFrequency\n } else {\n console.error('Invalid value for --frequency. Use: always, daily, weekly')\n process.exit(1)\n }\n }\n\n await sourceConfig({ autoPull, frequency })\n })\n\nprogram\n .command('doctor')\n .description('Diagnose setup issues')\n .action(async () => {\n await doctor()\n })\n\nprogram.parse()\n","import { join } from 'node:path'\nimport {\n loadConfig,\n saveConfig,\n createConfig,\n configExists,\n expandTilde,\n fileExists,\n ensureDir,\n cloneRepo,\n isGitRepo,\n getRemoteUrl\n} from '../lib/index.js'\nimport {\n intro,\n outro,\n log,\n spinner,\n isCancel,\n selectSourceType,\n inputSourcePath,\n inputGitUrl,\n inputClonePath,\n selectPullFrequency,\n selectWindowsShell\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { isWindows, detectWindowsShell } from '../lib/platform.js'\nimport type { SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\ninterface InitOptions {\n force?: boolean\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro(messages.initWelcome)\n\n // Check if already configured\n if (!options.force && await configExists()) {\n log.warn(messages.initAlreadyExists)\n return\n }\n\n // Select source type\n const sourceType = await selectSourceType()\n if (isCancel(sourceType)) {\n log.info('Setup cancelled.')\n return\n }\n\n let sourcePath: string\n let remote: string | undefined\n let detectedSourceType: SourceType = sourceType as SourceType\n\n if (sourceType === 'git') {\n // Git clone flow with retry\n while (true) {\n const gitUrl = await inputGitUrl()\n if (isCancel(gitUrl)) {\n log.info('Setup cancelled.')\n return\n }\n\n const clonePath = await inputClonePath()\n if (isCancel(clonePath)) {\n log.info('Setup cancelled.')\n return\n }\n\n const expandedClonePath = expandTilde(clonePath as string)\n\n const s = spinner()\n s.start('Cloning repository...')\n\n try {\n ensureDir(join(expandedClonePath, '..'))\n await cloneRepo(gitUrl as string, expandedClonePath)\n s.stop('Repository cloned successfully.')\n sourcePath = expandedClonePath\n remote = gitUrl as string\n break\n } catch (error) {\n s.stop('Failed to clone repository.')\n log.error(error instanceof Error ? error.message : String(error))\n log.info('Please try again.')\n }\n }\n } else {\n // Local path flow with retry\n while (true) {\n const localPath = await inputSourcePath()\n if (isCancel(localPath)) {\n log.info('Setup cancelled.')\n return\n }\n\n const expandedPath = expandTilde(localPath as string)\n\n if (!fileExists(expandedPath)) {\n log.error(messages.sourceNotFound(expandedPath))\n log.info('Please try again.')\n continue\n }\n\n sourcePath = expandedPath\n\n // Auto-detect if it's a git repo with a remote\n if (isGitRepo(expandedPath)) {\n const detectedRemote = await getRemoteUrl(expandedPath)\n if (detectedRemote) {\n detectedSourceType = 'git'\n remote = detectedRemote\n log.info(`Detected git repository with remote: ${detectedRemote}`)\n }\n }\n break\n }\n }\n\n // Select pull frequency\n const pullFrequency = await selectPullFrequency()\n if (isCancel(pullFrequency)) {\n log.info('Setup cancelled.')\n return\n }\n\n // Windows shell selection\n let shell: WindowsShell | undefined\n if (isWindows()) {\n const detectedShell = detectWindowsShell()\n if (detectedShell) {\n log.info(`Detected shell: ${detectedShell}`)\n shell = detectedShell\n } else {\n const selectedShell = await selectWindowsShell()\n if (isCancel(selectedShell)) {\n log.info('Setup cancelled.')\n return\n }\n shell = selectedShell as WindowsShell\n }\n }\n\n // Create and save config\n const config = createConfig({\n sourceType: detectedSourceType,\n sourcePath,\n remote,\n autoPull: true,\n pullFrequency: pullFrequency as PullFrequency,\n shell\n })\n\n await saveConfig(config)\n\n outro(messages.initSuccess)\n}\n","import { parse, stringify } from 'yaml'\nimport { getConfigPath, getConfigDir } from './paths.js'\nimport { fileExists, readTextFile, writeTextFile, ensureDir } from './files.js'\nimport { DEFAULT_CONFIG } from '../types/index.js'\nimport type { GlobalConfig, SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\nexport async function loadConfig(): Promise<GlobalConfig | null> {\n const configPath = getConfigPath()\n\n if (!fileExists(configPath)) {\n return null\n }\n\n const content = await readTextFile(configPath)\n const config = parse(content) as GlobalConfig\n\n return config\n}\n\nexport async function saveConfig(config: GlobalConfig): Promise<void> {\n const configPath = getConfigPath()\n ensureDir(getConfigDir())\n\n const content = stringify(config, { indent: 2 })\n await writeTextFile(configPath, content)\n}\n\nexport async function configExists(): Promise<boolean> {\n return fileExists(getConfigPath())\n}\n\nexport function createConfig(options: {\n sourceType: SourceType\n sourcePath: string\n remote?: string\n autoPull?: boolean\n pullFrequency?: PullFrequency\n shell?: WindowsShell\n}): GlobalConfig {\n const config: GlobalConfig = {\n ...DEFAULT_CONFIG,\n source: {\n type: options.sourceType,\n path: options.sourcePath,\n remote: options.remote\n },\n settings: {\n autoPull: options.autoPull ?? true,\n pullFrequency: options.pullFrequency ?? 'daily'\n }\n }\n\n if (options.shell) {\n config.platform = { shell: options.shell }\n }\n\n return config\n}\n\nexport async function updateConfigLastPull(): Promise<void> {\n const config = await loadConfig()\n if (config) {\n config.settings.lastPull = new Date().toISOString()\n await saveConfig(config)\n }\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport envPaths from 'env-paths'\n\nconst paths = envPaths('rulekeeper', { suffix: '' })\n\nexport function getConfigDir(): string {\n return paths.config\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), 'config.yaml')\n}\n\nexport function getClaudeDir(projectPath: string = process.cwd()): string {\n return join(projectPath, '.claude')\n}\n\nexport function getRulekeeperDir(projectPath: string = process.cwd()): string {\n return join(projectPath, '.rulekeeper')\n}\n\nexport function getManifestPath(projectPath: string = process.cwd()): string {\n return join(getRulekeeperDir(projectPath), 'manifest.yaml')\n}\n\nexport function getHomeDir(): string {\n return homedir()\n}\n\nexport function expandTilde(path: string): string {\n if (path.startsWith('~')) {\n return join(getHomeDir(), path.slice(1))\n }\n return path\n}\n","import { existsSync, mkdirSync } from 'node:fs'\nimport { readFile, writeFile, copyFile as fsCopyFile, readdir, unlink, rm } from 'node:fs/promises'\nimport { dirname, join, basename } from 'node:path'\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true })\n }\n}\n\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath)\n}\n\nexport async function readTextFile(filePath: string): Promise<string> {\n return await readFile(filePath, 'utf-8')\n}\n\nexport async function writeTextFile(filePath: string, content: string): Promise<void> {\n ensureDir(dirname(filePath))\n await writeFile(filePath, content, 'utf-8')\n}\n\nexport async function copyFile(source: string, dest: string): Promise<void> {\n ensureDir(dirname(dest))\n await fsCopyFile(source, dest)\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n if (existsSync(filePath)) {\n await unlink(filePath)\n }\n}\n\nexport async function deleteDir(dirPath: string): Promise<void> {\n if (existsSync(dirPath)) {\n await rm(dirPath, { recursive: true, force: true })\n }\n}\n\nexport async function listFiles(dirPath: string, extension?: string): Promise<string[]> {\n if (!existsSync(dirPath)) {\n return []\n }\n\n const entries = await readdir(dirPath, { withFileTypes: true })\n let files = entries\n .filter(entry => entry.isFile())\n .map(entry => entry.name)\n\n if (extension) {\n files = files.filter(file => file.endsWith(extension))\n }\n\n return files\n}\n\nexport function getRuleName(filename: string): string {\n // Remove .md extension to get rule name\n return basename(filename, '.md')\n}\n\nexport function getRuleFilename(ruleName: string): string {\n // Remove .md extension if already present, then add it back\n // This handles both \"laravel\" and \"laravel.md\" inputs\n const baseName = ruleName.toLowerCase().endsWith('.md')\n ? ruleName.slice(0, -3)\n : ruleName\n return `${baseName}.md`\n}\n\nexport function normalizeRuleName(ruleName: string): string {\n // Normalize rule name: remove .md extension and lowercase\n const name = ruleName.toLowerCase().endsWith('.md')\n ? ruleName.slice(0, -3)\n : ruleName\n return name.toLowerCase()\n}\n\nexport function findRuleMatch(\n input: string,\n availableRules: string[]\n): string | null {\n // Find a rule case-insensitively\n const normalizedInput = normalizeRuleName(input)\n\n // First try exact match (case-insensitive)\n const match = availableRules.find(\n rule => normalizeRuleName(rule) === normalizedInput\n )\n\n return match ?? null\n}\n","export type SourceType = 'local' | 'git'\nexport type PullFrequency = 'always' | 'daily' | 'weekly' | 'never'\nexport type WindowsShell = 'standard' | 'gitbash' | 'wsl'\n\nexport interface SourceConfig {\n type: SourceType\n path: string\n remote?: string\n}\n\nexport interface SettingsConfig {\n autoPull: boolean\n pullFrequency: PullFrequency\n lastPull?: string\n}\n\nexport interface PlatformConfig {\n shell?: WindowsShell\n}\n\nexport interface GlobalConfig {\n version: number\n source: SourceConfig\n settings: SettingsConfig\n platform?: PlatformConfig\n}\n\nexport const DEFAULT_CONFIG: GlobalConfig = {\n version: 1,\n source: {\n type: 'local',\n path: ''\n },\n settings: {\n autoPull: true,\n pullFrequency: 'daily'\n }\n}\n","export type RuleStatus = 'synced' | 'outdated' | 'diverged' | 'detached'\n\nexport interface RuleEntry {\n file: string\n sourceHash: string\n localHash: string\n status: RuleStatus\n installedAt: string\n updatedAt: string\n detachedAt?: string\n}\n\nexport interface ProjectManifest {\n version: number\n rules: Record<string, RuleEntry>\n}\n\nexport const DEFAULT_MANIFEST: ProjectManifest = {\n version: 1,\n rules: {}\n}\n\nexport interface StatusCheckResult {\n status: RuleStatus\n localChanged: boolean\n sourceChanged: boolean\n localExists: boolean\n sourceExists: boolean\n currentLocalHash?: string\n currentSourceHash?: string\n}\n","import { parse, stringify } from 'yaml'\nimport { getManifestPath, getRulekeeperDir } from './paths.js'\nimport { fileExists, readTextFile, writeTextFile, ensureDir } from './files.js'\nimport { DEFAULT_MANIFEST } from '../types/index.js'\nimport type { ProjectManifest, RuleEntry, RuleStatus } from '../types/index.js'\n\nexport async function loadManifest(projectPath: string = process.cwd()): Promise<ProjectManifest | null> {\n const manifestPath = getManifestPath(projectPath)\n\n if (!fileExists(manifestPath)) {\n return null\n }\n\n const content = await readTextFile(manifestPath)\n const manifest = parse(content) as ProjectManifest\n\n return manifest\n}\n\nexport async function saveManifest(manifest: ProjectManifest, projectPath: string = process.cwd()): Promise<void> {\n const manifestPath = getManifestPath(projectPath)\n ensureDir(getRulekeeperDir(projectPath))\n\n const content = stringify(manifest, { indent: 2 })\n await writeTextFile(manifestPath, content)\n}\n\nexport async function manifestExists(projectPath: string = process.cwd()): Promise<boolean> {\n return fileExists(getManifestPath(projectPath))\n}\n\nexport async function getOrCreateManifest(projectPath: string = process.cwd()): Promise<ProjectManifest> {\n const manifest = await loadManifest(projectPath)\n return manifest ?? { ...DEFAULT_MANIFEST }\n}\n\nexport function createRuleEntry(options: {\n file: string\n sourceHash: string\n localHash: string\n status?: RuleStatus\n}): RuleEntry {\n const now = new Date().toISOString()\n return {\n file: options.file,\n sourceHash: options.sourceHash,\n localHash: options.localHash,\n status: options.status ?? 'synced',\n installedAt: now,\n updatedAt: now\n }\n}\n\nexport function updateRuleEntry(entry: RuleEntry, updates: Partial<RuleEntry>): RuleEntry {\n return {\n ...entry,\n ...updates,\n updatedAt: new Date().toISOString()\n }\n}\n\nexport async function addRuleToManifest(\n ruleName: string,\n entry: RuleEntry,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await getOrCreateManifest(projectPath)\n manifest.rules[ruleName] = entry\n await saveManifest(manifest, projectPath)\n}\n\nexport async function removeRuleFromManifest(\n ruleName: string,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await loadManifest(projectPath)\n if (manifest && manifest.rules[ruleName]) {\n delete manifest.rules[ruleName]\n await saveManifest(manifest, projectPath)\n }\n}\n\nexport async function updateRuleInManifest(\n ruleName: string,\n updates: Partial<RuleEntry>,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await loadManifest(projectPath)\n if (manifest && manifest.rules[ruleName]) {\n manifest.rules[ruleName] = updateRuleEntry(manifest.rules[ruleName], updates)\n await saveManifest(manifest, projectPath)\n }\n}\n","import { join } from 'node:path'\nimport { fileExists, listFiles, getRuleFilename, getRuleName } from './files.js'\nimport { hashFile } from './hash.js'\nimport type { GlobalConfig } from '../types/index.js'\n\nexport interface AvailableRule {\n name: string\n file: string\n path: string\n}\n\n// Files to ignore when listing available rules (case-insensitive)\nconst IGNORED_FILES = ['readme.md']\n\nexport async function getAvailableRules(config: GlobalConfig): Promise<AvailableRule[]> {\n const sourcePath = config.source.path\n\n if (!fileExists(sourcePath)) {\n return []\n }\n\n const files = await listFiles(sourcePath, '.md')\n const filteredFiles = files.filter(file => !IGNORED_FILES.includes(file.toLowerCase()))\n\n return filteredFiles.map(file => ({\n name: getRuleName(file),\n file,\n path: join(sourcePath, file)\n }))\n}\n\nexport async function getRuleSourcePath(ruleName: string, config: GlobalConfig): Promise<string | null> {\n const filename = getRuleFilename(ruleName)\n const rulePath = join(config.source.path, filename)\n\n if (!fileExists(rulePath)) {\n return null\n }\n\n return rulePath\n}\n\nexport async function getRuleSourceHash(ruleName: string, config: GlobalConfig): Promise<string | null> {\n const rulePath = await getRuleSourcePath(ruleName, config)\n\n if (!rulePath) {\n return null\n }\n\n return await hashFile(rulePath)\n}\n\nexport function validateSourcePath(path: string): { valid: boolean; error?: string } {\n if (!path) {\n return { valid: false, error: 'Source path is required' }\n }\n\n if (!fileExists(path)) {\n return { valid: false, error: `Source path does not exist: ${path}` }\n }\n\n return { valid: true }\n}\n\nexport function isGitUrl(url: string): boolean {\n return (\n url.startsWith('git@') ||\n url.startsWith('https://github.com') ||\n url.startsWith('https://gitlab.com') ||\n url.startsWith('https://bitbucket.org') ||\n url.endsWith('.git')\n )\n}\n","import { createHash } from 'node:crypto'\nimport { readFile } from 'node:fs/promises'\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath)\n const hash = createHash('sha256').update(content).digest('hex')\n return `sha256:${hash}`\n}\n\nexport async function hashContent(content: string | Buffer): Promise<string> {\n const hash = createHash('sha256').update(content).digest('hex')\n return `sha256:${hash}`\n}\n\nexport function compareHashes(hash1: string, hash2: string): boolean {\n return hash1 === hash2\n}\n","import simpleGit, { SimpleGit } from 'simple-git'\nimport { fileExists } from './files.js'\nimport { join } from 'node:path'\nimport type { GlobalConfig } from '../types/index.js'\n\nexport function isGitRepo(path: string): boolean {\n return fileExists(join(path, '.git'))\n}\n\nexport async function cloneRepo(url: string, targetPath: string): Promise<void> {\n const git = simpleGit()\n await git.clone(url, targetPath)\n}\n\nexport async function pullRepo(path: string): Promise<void> {\n const git = simpleGit(path)\n await git.pull()\n}\n\nexport async function hasRemote(path: string): Promise<boolean> {\n if (!isGitRepo(path)) return false\n\n const git = simpleGit(path)\n try {\n const remotes = await git.getRemotes()\n return remotes.length > 0\n } catch {\n return false\n }\n}\n\nexport async function getRemoteUrl(path: string): Promise<string | null> {\n if (!isGitRepo(path)) return null\n\n const git = simpleGit(path)\n try {\n const remotes = await git.getRemotes(true)\n const origin = remotes.find(r => r.name === 'origin')\n return origin?.refs?.fetch ?? null\n } catch {\n return null\n }\n}\n\nexport function shouldPullFromRemote(config: GlobalConfig): boolean {\n if (!config.settings.autoPull) return false\n if (config.settings.pullFrequency === 'never') return false\n if (!config.settings.lastPull) return true\n\n const lastPull = new Date(config.settings.lastPull)\n const now = new Date()\n const hoursSinceLastPull = (now.getTime() - lastPull.getTime()) / (1000 * 60 * 60)\n\n switch (config.settings.pullFrequency) {\n case 'always':\n return true\n case 'daily':\n return hoursSinceLastPull >= 24\n case 'weekly':\n return hoursSinceLastPull >= 168\n default:\n return false\n }\n}\n\nexport async function pullSourceIfNeeded(config: GlobalConfig): Promise<{ pulled: boolean; error?: string }> {\n const sourcePath = config.source.path\n\n if (!isGitRepo(sourcePath)) {\n return { pulled: false }\n }\n\n if (!shouldPullFromRemote(config)) {\n return { pulled: false }\n }\n\n if (!(await hasRemote(sourcePath))) {\n return { pulled: false }\n }\n\n try {\n await pullRepo(sourcePath)\n return { pulled: true }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { pulled: false, error: message }\n }\n}\n","import type { WindowsShell } from '../types/index.js'\n\nexport function isWindows(): boolean {\n return process.platform === 'win32'\n}\n\nexport function isMac(): boolean {\n return process.platform === 'darwin'\n}\n\nexport function isLinux(): boolean {\n return process.platform === 'linux'\n}\n\nexport function isWSL(): boolean {\n // WSL runs as Linux, not Windows\n if (process.platform !== 'linux') return false\n\n // Check for WSL-specific indicators\n return !!(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP)\n}\n\nexport function detectWindowsShell(): WindowsShell | null {\n // If we're in WSL, platform is linux but we're in a Windows context\n if (isWSL()) {\n return 'wsl'\n }\n\n if (!isWindows()) return null\n\n // Git Bash sets MSYSTEM (MINGW64, MINGW32, MSYS, etc.)\n // Check this FIRST as WSLENV can be set even outside WSL\n if (process.env.MSYSTEM) {\n return 'gitbash'\n }\n\n return 'standard'\n}\n\nexport function getPlatformName(): string {\n if (isWSL()) return 'WSL'\n if (isWindows()) return 'Windows'\n if (isMac()) return 'macOS'\n if (isLinux()) return 'Linux'\n return process.platform\n}\n","import pc from 'picocolors'\nimport type { RuleStatus } from '../types/index.js'\n\nexport function formatRuleStatus(status: RuleStatus): string {\n switch (status) {\n case 'synced':\n return pc.green('✓')\n case 'outdated':\n return pc.yellow('↓')\n case 'diverged':\n return pc.red('⚠')\n case 'detached':\n return pc.dim('○')\n default:\n return pc.dim('?')\n }\n}\n\nexport function formatRuleStatusText(status: RuleStatus): string {\n switch (status) {\n case 'synced':\n return pc.green('synced')\n case 'outdated':\n return pc.yellow('outdated')\n case 'diverged':\n return pc.red('diverged')\n case 'detached':\n return pc.dim('detached')\n default:\n return pc.dim('unknown')\n }\n}\n\nexport function formatRuleLine(name: string, status: RuleStatus, details?: string): string {\n const icon = formatRuleStatus(status)\n const statusText = formatRuleStatusText(status)\n const detailsPart = details ? pc.dim(` (${details})`) : ''\n\n return ` ${icon} ${name.padEnd(20)} ${statusText}${detailsPart}`\n}\n\nexport function formatError(message: string): string {\n return pc.red(`✗ ${message}`)\n}\n\nexport function formatSuccess(message: string): string {\n return pc.green(`✓ ${message}`)\n}\n\nexport function formatWarning(message: string): string {\n return pc.yellow(`⚠ ${message}`)\n}\n\nexport function formatInfo(message: string): string {\n return pc.blue(`ℹ ${message}`)\n}\n\nexport function formatDim(message: string): string {\n return pc.dim(message)\n}\n\nexport function formatPath(path: string): string {\n return pc.cyan(path)\n}\n\nexport function formatCommand(command: string): string {\n return pc.cyan(`\\`${command}\\``)\n}\n\nexport function formatHeader(text: string): string {\n return pc.bold(text)\n}\n\nexport function formatDiffAdd(line: string): string {\n return pc.green(`+ ${line}`)\n}\n\nexport function formatDiffRemove(line: string): string {\n return pc.red(`- ${line}`)\n}\n\nexport function formatDiffContext(line: string): string {\n return pc.dim(` ${line}`)\n}\n\nexport function formatDiffHeader(line: string): string {\n return pc.cyan(line)\n}\n","import pc from 'picocolors'\nimport { formatCommand, formatPath } from './format.js'\n\nexport const messages = {\n // General\n notConfigured: `RuleKeeper is not configured. Run ${formatCommand('rk init')} first.`,\n noManifest: `No RuleKeeper manifest found. Run ${formatCommand('rk add')} first.`,\n noClaudeDir: `No .claude/ directory found. Are you in a project root?`,\n\n // Init\n initWelcome: 'Welcome to RuleKeeper!',\n initSuccess: 'RuleKeeper is now configured.',\n initAlreadyExists: 'RuleKeeper is already configured. Use --force to reconfigure.',\n\n // Source\n sourceNotFound: (path: string) => `Source path does not exist: ${formatPath(path)}`,\n sourceInvalid: 'Invalid source path or URL.',\n sourceUpdated: (path: string) => `Source updated to: ${formatPath(path)}`,\n\n // Add\n addSuccess: (count: number) => `Added ${count} rule${count !== 1 ? 's' : ''}.`,\n addConflict: (files: string[]) =>\n `The following files already exist in .claude/:\\n${files.map(f => ` - ${f}`).join('\\n')}`,\n addNoRules: 'No rules specified. Use --all to add all available rules.',\n ruleNotFound: (name: string) => `Rule '${name}' not found in source.`,\n\n // Remove\n removeSuccess: (count: number) => `Removed ${count} rule${count !== 1 ? 's' : ''}.`,\n removeNotInstalled: (name: string) => `Rule '${name}' is not installed.`,\n\n // Status\n statusAllSynced: 'All rules are synced.',\n statusNeedsAttention: (count: number) =>\n `${count} rule${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} attention. Run ${formatCommand('rk pull')} to update.`,\n statusOffline: pc.dim('⚠ Could not check for updates (offline?)'),\n\n // Pull\n pullSuccess: (count: number) => `${count} rule${count !== 1 ? 's' : ''} updated.`,\n pullSkipped: (count: number) => `${count} rule${count !== 1 ? 's' : ''} skipped.`,\n pullDetached: (count: number) => `${count} rule${count !== 1 ? 's' : ''} detached.`,\n pullUpToDate: 'All rules are up to date.',\n pullDiverged: (name: string) => `${name}.md has local changes`,\n pullDivergedAndOutdated: (name: string) => `${name}.md has local changes AND source has been updated`,\n\n // Detach/Attach\n detachSuccess: (name: string) => `Rule '${name}' is now detached.`,\n detachAlready: (name: string) => `Rule '${name}' is already detached.`,\n attachSuccess: (name: string) => `Rule '${name}' is now attached.`,\n attachAlready: (name: string) => `Rule '${name}' is already attached.`,\n\n // Diff\n diffNoDifference: (name: string) => `No difference found for '${name}'.`,\n diffNoRules: 'No diverged rules to show.',\n\n // Doctor\n doctorAllGood: 'All checks passed.',\n doctorIssuesFound: (count: number) => `${count} issue${count !== 1 ? 's' : ''} found.`,\n\n // Errors\n errorGeneric: (err: string) => `Error: ${err}`,\n errorMissingSource: (name: string) => `Source file for '${name}' no longer exists.`,\n errorMissingLocal: (name: string) => `Local file for '${name}' is missing.`\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\nimport type { SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\nexport type DivergenceAction = 'overwrite' | 'detach' | 'skip' | 'cancel' | 'view-diff'\nexport type MissingSourceAction = 'keep' | 'remove'\nexport type MissingLocalAction = 'restore' | 'remove'\nexport type AttachAction = 'overwrite' | 'keep' | 'cancel'\n\nexport function isCancel(value: unknown): boolean {\n return p.isCancel(value)\n}\n\nexport async function confirmOverwrite(files: string[]): Promise<boolean> {\n const result = await p.confirm({\n message: `${files.length} file${files.length !== 1 ? 's' : ''} will be overwritten. Continue?`\n })\n\n return result === true\n}\n\nexport async function selectSourceType(): Promise<SourceType | symbol> {\n return await p.select({\n message: 'Where are your Claude rules stored?',\n options: [\n { value: 'local', label: 'Local folder', hint: 'Already cloned git repo or static folder' },\n { value: 'git', label: 'Git repository', hint: 'Clone now from URL' }\n ]\n }) as SourceType | symbol\n}\n\nexport async function inputSourcePath(): Promise<string | symbol> {\n return await p.text({\n message: 'Enter the path to your rules folder:',\n placeholder: '~/Documents/claude-rules',\n validate: (value) => {\n if (!value) return 'Path is required'\n return undefined\n }\n })\n}\n\nexport async function inputGitUrl(): Promise<string | symbol> {\n return await p.text({\n message: 'Enter the Git repository URL:',\n placeholder: 'https://github.com/adxmcollins/rulekeeper-rules.git',\n validate: (value) => {\n if (!value) return 'URL is required'\n return undefined\n }\n })\n}\n\nexport async function inputClonePath(): Promise<string | symbol> {\n return await p.text({\n message: 'Where should the repository be cloned?',\n placeholder: '~/Documents/claude-rules',\n validate: (value) => {\n if (!value) return 'Path is required'\n return undefined\n }\n })\n}\n\nexport async function selectPullFrequency(): Promise<PullFrequency | symbol> {\n return await p.select({\n message: 'How often should RuleKeeper check for updates?',\n options: [\n { value: 'daily', label: 'Daily', hint: 'Recommended' },\n { value: 'always', label: 'Always', hint: 'Every command' },\n { value: 'weekly', label: 'Weekly' },\n { value: 'never', label: 'Never', hint: 'Manual only' }\n ]\n }) as PullFrequency | symbol\n}\n\nexport async function selectWindowsShell(): Promise<WindowsShell | symbol> {\n return await p.select({\n message: 'Which shell environment are you using?',\n options: [\n { value: 'standard', label: 'Standard (CMD/PowerShell)' },\n { value: 'gitbash', label: 'Git Bash' },\n { value: 'wsl', label: 'WSL (Windows Subsystem for Linux)' }\n ]\n }) as WindowsShell | symbol\n}\n\nexport async function selectRulesToAdd(available: string[], installed: string[]): Promise<string[] | symbol> {\n const options = available.map(rule => ({\n value: rule,\n label: rule,\n hint: installed.includes(rule) ? 'already installed' : undefined\n }))\n\n return await p.multiselect({\n message: 'Select rules to add:',\n options,\n required: true\n }) as string[] | symbol\n}\n\nexport async function handleDivergedRule(\n ruleName: string,\n sourceAlsoChanged: boolean,\n isSingleRule: boolean\n): Promise<DivergenceAction | symbol> {\n const message = sourceAlsoChanged\n ? `${ruleName}.md has local changes AND source has been updated`\n : `${ruleName}.md has local changes`\n\n p.log.warn(message)\n\n const options: { value: DivergenceAction; label: string; hint: string }[] = [\n {\n value: 'overwrite',\n label: 'Overwrite',\n hint: 'Replace with source version (local changes will be lost)'\n },\n {\n value: 'detach',\n label: 'Detach',\n hint: 'Keep local version, stop tracking this rule'\n }\n ]\n\n if (sourceAlsoChanged) {\n options.push({\n value: 'view-diff',\n label: 'View diff',\n hint: 'See differences before deciding'\n })\n }\n\n options.push(\n isSingleRule\n ? { value: 'cancel', label: 'Cancel', hint: 'Abort this operation' }\n : { value: 'skip', label: 'Skip', hint: 'Do nothing for now' }\n )\n\n const action = await p.select({\n message: 'What would you like to do?',\n options\n })\n\n if (p.isCancel(action)) {\n return isSingleRule ? 'cancel' : 'skip'\n }\n\n return action as DivergenceAction\n}\n\nexport async function handleMissingSource(ruleName: string): Promise<MissingSourceAction | symbol> {\n p.log.warn(`${ruleName}.md - source file no longer exists`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'keep', label: 'Keep local', hint: 'Detach and keep the local file' },\n { value: 'remove', label: 'Remove', hint: 'Delete from project and manifest' }\n ]\n }) as MissingSourceAction | symbol\n}\n\nexport async function handleMissingLocal(ruleName: string): Promise<MissingLocalAction | symbol> {\n p.log.warn(`${ruleName}.md - local file missing`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'restore', label: 'Restore', hint: 'Copy from source' },\n { value: 'remove', label: 'Remove', hint: 'Remove from manifest' }\n ]\n }) as MissingLocalAction | symbol\n}\n\nexport async function handleAttachDiffers(ruleName: string): Promise<AttachAction | symbol> {\n p.log.warn(`${ruleName}.md differs from source version`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'overwrite', label: 'Overwrite local', hint: 'Replace with source version' },\n { value: 'keep', label: 'Keep local', hint: 'Attach but keep local version (will show as diverged)' },\n { value: 'cancel', label: 'Cancel', hint: 'Keep detached' }\n ]\n }) as AttachAction | symbol\n}\n\nexport function spinner() {\n return p.spinner()\n}\n\nexport function intro(message: string) {\n p.intro(pc.bgCyan(pc.black(` ${message} `)))\n}\n\nexport function outro(message: string) {\n p.outro(message)\n}\n\nexport const log = p.log\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getOrCreateManifest,\n createRuleEntry,\n getAvailableRules,\n getRuleSourcePath,\n getClaudeDir,\n fileExists,\n copyFile,\n ensureDir,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport {\n log,\n spinner,\n isCancel,\n confirmOverwrite,\n selectRulesToAdd,\n handleDivergedRule\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface AddOptions {\n all?: boolean\n}\n\nexport async function add(rules: string[], options: AddOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop(pullResult.error ? messages.statusOffline : 'Source is up to date.')\n\n // Get available rules\n const availableRules = await getAvailableRules(config)\n if (availableRules.length === 0) {\n log.error('No rules found in source.')\n process.exit(1)\n }\n\n // Get installed rules\n const manifest = await loadManifest()\n const installedRules = manifest ? Object.keys(manifest.rules) : []\n\n // Determine which rules to add\n let rulesToAdd: string[]\n\n if (options.all) {\n rulesToAdd = availableRules.map(r => r.name)\n } else if (rules.length > 0) {\n rulesToAdd = rules\n } else {\n // Interactive selection\n const selected = await selectRulesToAdd(\n availableRules.map(r => r.name),\n installedRules\n )\n\n if (isCancel(selected)) {\n log.info('Cancelled.')\n return\n }\n\n rulesToAdd = selected as string[]\n }\n\n if (rulesToAdd.length === 0) {\n log.warn(messages.addNoRules)\n return\n }\n\n // Resolve rules case-insensitively and validate they exist\n const availableRuleNames = availableRules.map(r => r.name)\n const resolvedRules: string[] = []\n const invalidRules: string[] = []\n\n for (const rule of rulesToAdd) {\n const match = findRuleMatch(rule, availableRuleNames)\n if (match) {\n resolvedRules.push(match)\n } else {\n invalidRules.push(rule)\n }\n }\n\n if (invalidRules.length > 0) {\n for (const rule of invalidRules) {\n log.error(messages.ruleNotFound(rule))\n }\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n ensureDir(claudeDir)\n\n // Copy rules and update manifest, handling conflicts\n const updatedManifest = await getOrCreateManifest()\n let addedCount = 0\n let skippedCount = 0\n\n for (const rule of resolvedRules) {\n const sourcePath = await getRuleSourcePath(rule, config)\n if (!sourcePath) continue\n\n const filename = getRuleFilename(rule)\n const targetPath = join(claudeDir, filename)\n const sourceHash = await hashFile(sourcePath)\n\n // Check if file already exists with local changes\n if (fileExists(targetPath)) {\n const localHash = await hashFile(targetPath)\n const entry = updatedManifest.rules[rule]\n\n // If already tracked and unchanged, just update\n if (entry && localHash === entry.localHash) {\n await copyFile(sourcePath, targetPath)\n const newHash = await hashFile(targetPath)\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: newHash,\n localHash: newHash\n })\n log.success(`Updated ${filename}`)\n addedCount++\n continue\n }\n\n // If file has local changes (tracked or untracked), ask user\n if (!entry || localHash !== entry.localHash) {\n const action = await handleDivergedRule(rule, false, false)\n\n if (isCancel(action) || action === 'skip') {\n skippedCount++\n continue\n }\n\n if (action === 'detach') {\n // Keep local file, mark as detached\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: sourceHash,\n localHash: localHash,\n status: 'detached'\n })\n updatedManifest.rules[rule].detachedAt = new Date().toISOString()\n log.info(`${filename} kept as detached`)\n continue\n }\n\n // Overwrite\n }\n }\n\n try {\n await copyFile(sourcePath, targetPath)\n const hash = await hashFile(targetPath)\n\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: hash,\n localHash: hash\n })\n\n log.success(`Added ${filename}`)\n addedCount++\n } catch (error) {\n log.error(`Failed to add ${filename}: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n await saveManifest(updatedManifest)\n\n if (addedCount > 0) {\n log.info(messages.addSuccess(addedCount))\n }\n if (skippedCount > 0) {\n log.info(`${skippedCount} rule(s) skipped.`)\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getClaudeDir,\n deleteFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport { log } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface RemoveOptions {\n keepFile?: boolean\n}\n\nexport async function remove(rules: string[], options: RemoveOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n if (rules.length === 0) {\n log.error('No rules specified.')\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n const manifestRules = Object.keys(manifest.rules)\n let removedCount = 0\n\n for (const rule of rules) {\n // Case-insensitive lookup\n const match = findRuleMatch(rule, manifestRules)\n if (!match) {\n log.warn(messages.removeNotInstalled(rule))\n continue\n }\n\n const filename = getRuleFilename(match)\n const targetPath = join(claudeDir, filename)\n\n // Delete file unless --keep-file is specified\n if (!options.keepFile) {\n try {\n await deleteFile(targetPath)\n } catch (error) {\n log.warn(`Could not delete ${filename}: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n // Remove from manifest\n delete manifest.rules[match]\n log.success(`Removed ${match}`)\n removedCount++\n }\n\n await saveManifest(manifest)\n\n if (removedCount > 0) {\n log.info(messages.removeSuccess(removedCount))\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n fileExists,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename\n} from '../lib/index.js'\nimport { log, spinner, formatRuleLine, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport type { RuleStatus, StatusCheckResult } from '../types/index.js'\n\nexport async function status(): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n const ruleNames = Object.keys(manifest.rules)\n if (ruleNames.length === 0) {\n log.info('No rules installed.')\n return\n }\n\n console.log('')\n console.log(formatHeader('RuleKeeper Status'))\n console.log('')\n\n const claudeDir = getClaudeDir()\n let needsAttention = 0\n\n for (const ruleName of ruleNames.sort()) {\n const entry = manifest.rules[ruleName]\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n const result = await checkRuleStatus(entry, localPath, sourcePath)\n let details: string | undefined\n\n switch (result.status) {\n case 'outdated':\n details = 'source updated'\n needsAttention++\n break\n case 'diverged':\n details = 'local changes detected'\n needsAttention++\n break\n case 'detached':\n break\n case 'synced':\n break\n }\n\n if (!result.localExists) {\n details = 'local file missing'\n needsAttention++\n } else if (!result.sourceExists) {\n details = 'source file missing'\n needsAttention++\n }\n\n console.log(formatRuleLine(ruleName + '.md', result.status, details))\n }\n\n console.log('')\n\n if (needsAttention > 0) {\n log.info(messages.statusNeedsAttention(needsAttention))\n } else {\n log.success(messages.statusAllSynced)\n }\n}\n\nasync function checkRuleStatus(\n entry: { status: RuleStatus; sourceHash: string; localHash: string },\n localPath: string,\n sourcePath: string\n): Promise<StatusCheckResult> {\n const localExists = fileExists(localPath)\n const sourceExists = fileExists(sourcePath)\n\n // If detached, always return detached regardless of file state\n if (entry.status === 'detached') {\n return {\n status: 'detached',\n localChanged: false,\n sourceChanged: false,\n localExists,\n sourceExists\n }\n }\n\n // Handle missing files\n if (!localExists || !sourceExists) {\n return {\n status: 'diverged',\n localChanged: !localExists,\n sourceChanged: !sourceExists,\n localExists,\n sourceExists\n }\n }\n\n // Calculate current hashes\n const currentLocalHash = await hashFile(localPath)\n const currentSourceHash = await hashFile(sourcePath)\n\n const localChanged = currentLocalHash !== entry.localHash\n const sourceChanged = currentSourceHash !== entry.sourceHash\n\n let status: RuleStatus\n\n if (localChanged) {\n status = 'diverged'\n } else if (sourceChanged) {\n status = 'outdated'\n } else {\n status = 'synced'\n }\n\n return {\n status,\n localChanged,\n sourceChanged,\n localExists,\n sourceExists,\n currentLocalHash,\n currentSourceHash\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getClaudeDir,\n fileExists,\n copyFile,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename,\n deleteFile,\n findRuleMatch\n} from '../lib/index.js'\nimport {\n log,\n spinner,\n handleDivergedRule,\n handleMissingSource,\n handleMissingLocal,\n isCancel\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { showDiff } from './diff.js'\nimport type { RuleStatus, RuleEntry } from '../types/index.js'\n\ninterface PullOptions {\n force?: boolean\n includeDetached?: boolean\n}\n\nexport async function pull(rules: string[], options: PullOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n // Determine which rules to process (case-insensitive matching)\n const manifestRules = Object.keys(manifest.rules)\n let rulesToProcess: string[]\n\n if (rules.length > 0) {\n rulesToProcess = []\n for (const rule of rules) {\n const match = findRuleMatch(rule, manifestRules)\n if (match) {\n rulesToProcess.push(match)\n } else {\n log.warn(`Rule '${rule}' not found in manifest`)\n }\n }\n } else {\n rulesToProcess = manifestRules\n }\n\n const results = {\n updated: [] as string[],\n skipped: [] as string[],\n detached: [] as string[],\n failed: [] as string[]\n }\n\n const claudeDir = getClaudeDir()\n const isSingleRule = rules.length === 1\n\n for (const ruleName of rulesToProcess) {\n const entry = manifest.rules[ruleName]\n\n if (!entry) {\n log.warn(`Rule '${ruleName}' not found in manifest`)\n results.failed.push(ruleName)\n continue\n }\n\n // Skip detached unless explicitly included\n if (entry.status === 'detached' && !options.includeDetached) {\n log.info(`○ ${ruleName}.md (detached - skipped)`)\n results.skipped.push(ruleName)\n continue\n }\n\n const filename = getRuleFilename(ruleName)\n const sourcePath = join(config.source.path, filename)\n const localPath = join(claudeDir, filename)\n\n // Handle missing source\n if (!fileExists(sourcePath)) {\n const action = await handleMissingSource(ruleName)\n if (isCancel(action)) {\n results.skipped.push(ruleName)\n continue\n }\n\n if (action === 'keep') {\n manifest.rules[ruleName] = {\n ...entry,\n status: 'detached',\n detachedAt: new Date().toISOString()\n }\n results.detached.push(ruleName)\n } else if (action === 'remove') {\n await deleteFile(localPath)\n delete manifest.rules[ruleName]\n log.success(`Removed ${ruleName}`)\n }\n continue\n }\n\n // Handle missing local\n if (!fileExists(localPath)) {\n const action = await handleMissingLocal(ruleName)\n if (isCancel(action)) {\n results.skipped.push(ruleName)\n continue\n }\n\n if (action === 'restore') {\n await copyFile(sourcePath, localPath)\n const hash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: hash,\n localHash: hash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n log.success(`Restored ${ruleName}.md`)\n results.updated.push(ruleName)\n } else if (action === 'remove') {\n delete manifest.rules[ruleName]\n log.success(`Removed ${ruleName} from manifest`)\n }\n continue\n }\n\n // Process the rule\n const result = await pullRule(\n ruleName,\n entry,\n sourcePath,\n localPath,\n manifest,\n options,\n isSingleRule\n )\n\n switch (result) {\n case 'updated':\n log.success(`✓ ${ruleName}.md updated`)\n results.updated.push(ruleName)\n break\n case 'detached':\n log.info(`○ ${ruleName}.md detached`)\n results.detached.push(ruleName)\n break\n case 'skipped':\n results.skipped.push(ruleName)\n break\n case 'cancelled':\n await saveManifest(manifest)\n return\n }\n }\n\n await saveManifest(manifest)\n\n // Summary\n console.log('')\n if (results.updated.length > 0) {\n log.success(messages.pullSuccess(results.updated.length))\n }\n if (results.detached.length > 0) {\n log.info(messages.pullDetached(results.detached.length))\n }\n if (results.failed.length > 0) {\n log.error(`${results.failed.length} rule(s) failed`)\n }\n if (results.updated.length === 0 && results.detached.length === 0 && results.failed.length === 0) {\n log.success(messages.pullUpToDate)\n }\n}\n\nasync function pullRule(\n ruleName: string,\n entry: RuleEntry,\n sourcePath: string,\n localPath: string,\n manifest: { rules: Record<string, RuleEntry> },\n options: PullOptions,\n isSingleRule: boolean\n): Promise<'updated' | 'skipped' | 'detached' | 'cancelled'> {\n // Calculate current hashes\n const currentLocalHash = await hashFile(localPath)\n const currentSourceHash = await hashFile(sourcePath)\n\n // Determine state\n const localChanged = currentLocalHash !== entry.localHash\n const sourceChanged = currentSourceHash !== entry.sourceHash\n\n // No changes anywhere - nothing to do\n if (!localChanged && !sourceChanged) {\n return 'skipped'\n }\n\n // Only source changed - safe to update\n if (!localChanged && sourceChanged) {\n await copyFile(sourcePath, localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: currentSourceHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n }\n\n // Local changed (diverged) - need to handle\n if (localChanged) {\n // Force flag overwrites without prompting\n if (options.force) {\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: newHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n }\n\n // Interactive handling\n let action = await handleDivergedRule(ruleName, sourceChanged, isSingleRule)\n\n // Handle view-diff loop\n while (action === 'view-diff') {\n await showDiff([ruleName])\n action = await handleDivergedRule(ruleName, sourceChanged, isSingleRule)\n }\n\n if (isCancel(action)) {\n return isSingleRule ? 'cancelled' : 'skipped'\n }\n\n switch (action) {\n case 'overwrite':\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: newHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n\n case 'detach':\n manifest.rules[ruleName] = {\n ...entry,\n status: 'detached',\n detachedAt: new Date().toISOString()\n }\n return 'detached'\n\n case 'skip':\n case 'cancel':\n return isSingleRule ? 'cancelled' : 'skipped'\n }\n }\n\n return 'skipped'\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n fileExists,\n readTextFile,\n hashFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport {\n log,\n formatDiffAdd,\n formatDiffRemove,\n formatDiffContext,\n formatDiffHeader,\n formatPath,\n formatHeader\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface DiffOptions {\n all?: boolean\n}\n\nexport async function diff(rules: string[], options: DiffOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n\n // Determine which rules to show diff for\n let rulesToDiff: string[]\n\n if (options.all) {\n // Find all diverged rules\n rulesToDiff = []\n for (const [ruleName, entry] of Object.entries(manifest.rules)) {\n if (entry.status === 'detached') continue\n\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n\n if (!fileExists(localPath)) continue\n\n const currentLocalHash = await hashFile(localPath)\n if (currentLocalHash !== entry.localHash) {\n rulesToDiff.push(ruleName)\n }\n }\n\n if (rulesToDiff.length === 0) {\n log.info(messages.diffNoRules)\n return\n }\n } else if (rules.length > 0) {\n // Case-insensitive lookup\n const manifestRules = Object.keys(manifest.rules)\n rulesToDiff = []\n for (const rule of rules) {\n const match = findRuleMatch(rule, manifestRules)\n if (match) {\n rulesToDiff.push(match)\n } else {\n log.warn(`Rule '${rule}' not found in manifest`)\n }\n }\n } else {\n log.error('Specify a rule name or use --all to see all diverged rules.')\n process.exit(1)\n }\n\n for (const ruleName of rulesToDiff) {\n const entry = manifest.rules[ruleName]\n if (!entry) continue\n\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n await showRuleDiff(ruleName, sourcePath, localPath)\n }\n}\n\nexport async function showDiff(rules: string[]): Promise<void> {\n return diff(rules, {})\n}\n\nasync function showRuleDiff(\n ruleName: string,\n sourcePath: string,\n localPath: string\n): Promise<void> {\n const sourceExists = fileExists(sourcePath)\n const localExists = fileExists(localPath)\n\n console.log('')\n console.log(formatHeader(`Comparing ${ruleName}.md`))\n console.log('')\n\n if (!sourceExists && !localExists) {\n log.warn('Both source and local files are missing')\n return\n }\n\n if (!sourceExists) {\n log.warn('Source file no longer exists')\n console.log(formatDiffHeader(`--- source (missing)`))\n console.log(formatDiffHeader(`+++ local (${formatPath(localPath)})`))\n return\n }\n\n if (!localExists) {\n log.warn('Local file is missing')\n console.log(formatDiffHeader(`--- source (${formatPath(sourcePath)})`))\n console.log(formatDiffHeader(`+++ local (missing)`))\n return\n }\n\n const sourceContent = await readTextFile(sourcePath)\n const localContent = await readTextFile(localPath)\n\n if (sourceContent === localContent) {\n log.info(messages.diffNoDifference(ruleName))\n return\n }\n\n console.log(formatDiffHeader(`--- source (${sourcePath})`))\n console.log(formatDiffHeader(`+++ local (${localPath})`))\n console.log('')\n\n // Simple line-by-line diff\n const sourceLines = sourceContent.split('\\n')\n const localLines = localContent.split('\\n')\n\n const diff = computeSimpleDiff(sourceLines, localLines)\n\n for (const line of diff) {\n if (line.type === 'add') {\n console.log(formatDiffAdd(line.content))\n } else if (line.type === 'remove') {\n console.log(formatDiffRemove(line.content))\n } else {\n console.log(formatDiffContext(line.content))\n }\n }\n\n console.log('')\n}\n\ninterface DiffLine {\n type: 'add' | 'remove' | 'context'\n content: string\n}\n\nfunction computeSimpleDiff(source: string[], local: string[]): DiffLine[] {\n // Simple diff algorithm - compare lines\n const result: DiffLine[] = []\n const maxLen = Math.max(source.length, local.length)\n\n // Build a map of source lines for quick lookup\n const sourceSet = new Set(source)\n const localSet = new Set(local)\n\n let si = 0\n let li = 0\n\n while (si < source.length || li < local.length) {\n if (si >= source.length) {\n // Remaining local lines are additions\n result.push({ type: 'add', content: local[li] })\n li++\n } else if (li >= local.length) {\n // Remaining source lines are removals\n result.push({ type: 'remove', content: source[si] })\n si++\n } else if (source[si] === local[li]) {\n // Lines match\n result.push({ type: 'context', content: source[si] })\n si++\n li++\n } else if (!localSet.has(source[si])) {\n // Source line not in local - it was removed\n result.push({ type: 'remove', content: source[si] })\n si++\n } else if (!sourceSet.has(local[li])) {\n // Local line not in source - it was added\n result.push({ type: 'add', content: local[li] })\n li++\n } else {\n // Both lines exist elsewhere - treat as removal then addition\n result.push({ type: 'remove', content: source[si] })\n result.push({ type: 'add', content: local[li] })\n si++\n li++\n }\n }\n\n return result\n}\n","import {\n loadConfig,\n loadManifest,\n getAvailableRules,\n pullSourceIfNeeded,\n updateConfigLastPull\n} from '../lib/index.js'\nimport { log, spinner, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport pc from 'picocolors'\n\ninterface ListOptions {\n installed?: boolean\n}\n\nexport async function list(options: ListOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking source...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n // Get installed rules\n const manifest = await loadManifest()\n const installedRules = manifest ? Object.keys(manifest.rules) : []\n\n if (options.installed) {\n // Show only installed rules\n if (installedRules.length === 0) {\n log.info('No rules installed.')\n return\n }\n\n console.log('')\n console.log(formatHeader('Installed Rules'))\n console.log('')\n\n for (const rule of installedRules.sort()) {\n const entry = manifest!.rules[rule]\n const statusHint = entry.status !== 'synced'\n ? pc.dim(` (${entry.status})`)\n : ''\n console.log(` ${rule}.md${statusHint}`)\n }\n } else {\n // Show all available rules\n const availableRules = await getAvailableRules(config)\n\n if (availableRules.length === 0) {\n log.info('No rules found in source.')\n return\n }\n\n console.log('')\n console.log(formatHeader('Available Rules'))\n console.log('')\n\n for (const rule of availableRules.sort((a, b) => a.name.localeCompare(b.name))) {\n const installed = installedRules.includes(rule.name)\n const icon = installed ? pc.green('✓') : pc.dim('○')\n const hint = installed ? pc.dim(' (installed)') : ''\n console.log(` ${icon} ${rule.name}.md${hint}`)\n }\n\n console.log('')\n console.log(pc.dim(`Source: ${config.source.path}`))\n }\n\n console.log('')\n}\n","import {\n loadConfig,\n loadManifest,\n updateRuleInManifest,\n findRuleMatch\n} from '../lib/index.js'\nimport { log } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\nexport async function detach(ruleName: string): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Case-insensitive lookup\n const match = findRuleMatch(ruleName, Object.keys(manifest.rules))\n if (!match) {\n log.error(`Rule '${ruleName}' not found in manifest.`)\n process.exit(1)\n }\n\n const entry = manifest.rules[match]\n if (entry.status === 'detached') {\n log.warn(messages.detachAlready(match))\n return\n }\n\n await updateRuleInManifest(match, {\n status: 'detached',\n detachedAt: new Date().toISOString()\n })\n\n log.success(messages.detachSuccess(match))\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n updateRuleInManifest,\n getClaudeDir,\n fileExists,\n hashFile,\n copyFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport { log, handleAttachDiffers, isCancel } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\nexport async function attach(ruleName: string): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Case-insensitive lookup\n const match = findRuleMatch(ruleName, Object.keys(manifest.rules))\n if (!match) {\n log.error(`Rule '${ruleName}' not found in manifest.`)\n process.exit(1)\n }\n\n const entry = manifest.rules[match]\n if (entry.status !== 'detached') {\n log.warn(messages.attachAlready(match))\n return\n }\n\n const claudeDir = getClaudeDir()\n const filename = getRuleFilename(match)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n // Check if source exists\n if (!fileExists(sourcePath)) {\n log.error(messages.errorMissingSource(match))\n process.exit(1)\n }\n\n // Check if local exists\n if (!fileExists(localPath)) {\n log.error(messages.errorMissingLocal(match))\n process.exit(1)\n }\n\n // Compare hashes\n const localHash = await hashFile(localPath)\n const sourceHash = await hashFile(sourcePath)\n\n if (localHash === sourceHash) {\n // Files match - just attach\n await updateRuleInManifest(match, {\n status: 'synced',\n sourceHash,\n localHash,\n detachedAt: undefined\n })\n log.success(messages.attachSuccess(match))\n return\n }\n\n // Files differ - ask user what to do\n const action = await handleAttachDiffers(match)\n\n if (isCancel(action)) {\n log.info('Cancelled.')\n return\n }\n\n switch (action) {\n case 'overwrite':\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n await updateRuleInManifest(match, {\n status: 'synced',\n sourceHash,\n localHash: newHash,\n detachedAt: undefined\n })\n log.success(messages.attachSuccess(match))\n break\n\n case 'keep':\n await updateRuleInManifest(match, {\n status: 'diverged',\n sourceHash,\n localHash,\n detachedAt: undefined\n })\n log.success(`${match} attached (will show as diverged)`)\n break\n\n case 'cancel':\n log.info('Cancelled.')\n break\n }\n}\n","import {\n loadConfig,\n saveConfig,\n expandTilde,\n fileExists,\n ensureDir,\n cloneRepo,\n pullRepo,\n isGitRepo,\n hasRemote,\n getRemoteUrl,\n isGitUrl\n} from '../lib/index.js'\nimport { log, spinner, formatPath, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { join } from 'node:path'\n\nexport async function sourceShow(): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n console.log('')\n console.log(formatHeader('Source Configuration'))\n console.log('')\n console.log(` Type: ${config.source.type}`)\n console.log(` Path: ${formatPath(config.source.path)}`)\n\n if (config.source.remote) {\n console.log(` Remote: ${config.source.remote}`)\n } else if (isGitRepo(config.source.path)) {\n const remote = await getRemoteUrl(config.source.path)\n if (remote) {\n console.log(` Remote: ${remote}`)\n }\n }\n\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n if (config.settings.lastPull) {\n console.log(` Last pull: ${new Date(config.settings.lastPull).toLocaleString()}`)\n }\n console.log('')\n}\n\nexport async function sourceSet(pathOrUrl: string): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n if (isGitUrl(pathOrUrl)) {\n // It's a git URL - clone it\n const s = spinner()\n s.start('Cloning repository...')\n\n // Determine clone path from URL\n const repoName = pathOrUrl.split('/').pop()?.replace('.git', '') || 'claude-rules'\n const clonePath = expandTilde(`~/Documents/${repoName}`)\n\n try {\n ensureDir(join(clonePath, '..'))\n await cloneRepo(pathOrUrl, clonePath)\n s.stop('Repository cloned successfully.')\n\n config.source = {\n type: 'git',\n path: clonePath,\n remote: pathOrUrl\n }\n } catch (error) {\n s.stop('Failed to clone repository.')\n log.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n } else {\n // It's a local path\n const expandedPath = expandTilde(pathOrUrl)\n\n if (!fileExists(expandedPath)) {\n log.error(messages.sourceNotFound(expandedPath))\n process.exit(1)\n }\n\n config.source = {\n type: 'local',\n path: expandedPath\n }\n\n // Check if it's a git repo with a remote\n if (isGitRepo(expandedPath)) {\n const remote = await getRemoteUrl(expandedPath)\n if (remote) {\n config.source.type = 'git'\n config.source.remote = remote\n }\n }\n }\n\n await saveConfig(config)\n log.success(messages.sourceUpdated(config.source.path))\n}\n\nexport async function sourcePull(): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n if (!isGitRepo(config.source.path)) {\n log.error('Source is not a git repository.')\n process.exit(1)\n }\n\n if (!(await hasRemote(config.source.path))) {\n log.error('Source repository has no remote configured.')\n process.exit(1)\n }\n\n const s = spinner()\n s.start('Pulling from remote...')\n\n try {\n await pullRepo(config.source.path)\n s.stop('Source updated successfully.')\n\n // Update last pull time\n config.settings.lastPull = new Date().toISOString()\n await saveConfig(config)\n } catch (error) {\n s.stop('Failed to pull from remote.')\n log.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n}\n\nimport type { PullFrequency } from '../types/index.js'\n\ninterface SourceConfigOptions {\n autoPull?: boolean\n frequency?: PullFrequency\n}\n\nexport async function sourceConfig(options: SourceConfigOptions): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // If no options provided, show current settings\n if (options.autoPull === undefined && options.frequency === undefined) {\n console.log('')\n console.log(formatHeader('Pull Settings'))\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n if (config.settings.lastPull) {\n console.log(` Last pull: ${new Date(config.settings.lastPull).toLocaleString()}`)\n }\n console.log('')\n console.log(' Use --auto-pull and --frequency to change settings.')\n console.log('')\n return\n }\n\n // Update settings\n if (options.autoPull !== undefined) {\n config.settings.autoPull = options.autoPull\n }\n\n if (options.frequency !== undefined) {\n config.settings.pullFrequency = options.frequency\n }\n\n await saveConfig(config)\n\n log.success('Settings updated.')\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n console.log('')\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n getRulekeeperDir,\n getConfigPath,\n fileExists,\n isGitRepo,\n hasRemote,\n getAvailableRules\n} from '../lib/index.js'\nimport { log, formatSuccess, formatError, formatWarning, formatHeader, formatPath } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport pc from 'picocolors'\n\ninterface DiagnosticResult {\n name: string\n status: 'pass' | 'warn' | 'fail'\n message: string\n}\n\nexport async function doctor(): Promise<void> {\n console.log('')\n console.log(formatHeader('RuleKeeper Diagnostics'))\n console.log('')\n\n const results: DiagnosticResult[] = []\n\n // Check 1: Global config exists\n const configPath = getConfigPath()\n if (fileExists(configPath)) {\n results.push({\n name: 'Global config',\n status: 'pass',\n message: `Found at ${formatPath(configPath)}`\n })\n } else {\n results.push({\n name: 'Global config',\n status: 'fail',\n message: `Not found. Run ${pc.cyan('rk init')} to configure.`\n })\n }\n\n // Load config for remaining checks\n const config = await loadConfig()\n\n if (config) {\n // Check 2: Source path exists\n if (fileExists(config.source.path)) {\n results.push({\n name: 'Source path',\n status: 'pass',\n message: formatPath(config.source.path)\n })\n } else {\n results.push({\n name: 'Source path',\n status: 'fail',\n message: `Path does not exist: ${formatPath(config.source.path)}`\n })\n }\n\n // Check 3: Source has rules\n if (fileExists(config.source.path)) {\n const availableRules = await getAvailableRules(config)\n if (availableRules.length > 0) {\n results.push({\n name: 'Source rules',\n status: 'pass',\n message: `${availableRules.length} rule(s) available`\n })\n } else {\n results.push({\n name: 'Source rules',\n status: 'warn',\n message: 'No .md files found in source'\n })\n }\n }\n\n // Check 4: Git remote (if git source)\n if (config.source.type === 'git' && fileExists(config.source.path)) {\n if (isGitRepo(config.source.path)) {\n if (await hasRemote(config.source.path)) {\n results.push({\n name: 'Git remote',\n status: 'pass',\n message: 'Remote configured'\n })\n } else {\n results.push({\n name: 'Git remote',\n status: 'warn',\n message: 'No remote configured - cannot auto-pull'\n })\n }\n } else {\n results.push({\n name: 'Git repository',\n status: 'fail',\n message: 'Source is configured as git but is not a git repository'\n })\n }\n }\n }\n\n // Check 5: Project setup (only if in a project)\n const claudeDir = getClaudeDir()\n const rulekeeperDir = getRulekeeperDir()\n\n if (fileExists(claudeDir)) {\n results.push({\n name: '.claude directory',\n status: 'pass',\n message: 'Found in current project'\n })\n } else {\n results.push({\n name: '.claude directory',\n status: 'warn',\n message: 'Not found - not in a Claude Code project?'\n })\n }\n\n // Check 6: Manifest\n const manifest = await loadManifest()\n if (manifest) {\n const ruleCount = Object.keys(manifest.rules).length\n results.push({\n name: 'RuleKeeper manifest',\n status: 'pass',\n message: `${ruleCount} rule(s) tracked`\n })\n\n // Check 7: Rule file integrity\n if (config && ruleCount > 0) {\n let missingCount = 0\n for (const [ruleName, entry] of Object.entries(manifest.rules)) {\n const localPath = join(claudeDir, entry.file)\n if (!fileExists(localPath)) {\n missingCount++\n }\n }\n\n if (missingCount > 0) {\n results.push({\n name: 'Rule files',\n status: 'warn',\n message: `${missingCount} tracked rule(s) missing local files`\n })\n } else {\n results.push({\n name: 'Rule files',\n status: 'pass',\n message: 'All tracked rules have local files'\n })\n }\n }\n } else if (fileExists(claudeDir)) {\n results.push({\n name: 'RuleKeeper manifest',\n status: 'warn',\n message: `No manifest. Run ${pc.cyan('rk add')} to start tracking rules.`\n })\n }\n\n // Display results\n let passCount = 0\n let warnCount = 0\n let failCount = 0\n\n for (const result of results) {\n let icon: string\n let color: (s: string) => string\n\n switch (result.status) {\n case 'pass':\n icon = '✓'\n color = pc.green\n passCount++\n break\n case 'warn':\n icon = '⚠'\n color = pc.yellow\n warnCount++\n break\n case 'fail':\n icon = '✗'\n color = pc.red\n failCount++\n break\n }\n\n console.log(` ${color(icon)} ${result.name}: ${result.message}`)\n }\n\n console.log('')\n\n if (failCount > 0) {\n log.error(messages.doctorIssuesFound(failCount))\n } else if (warnCount > 0) {\n log.warn(`${warnCount} warning(s) found.`)\n } else {\n log.success(messages.doctorAllGood)\n }\n}\n"],"mappings":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,OAAO,oBAAoB;;;ACF3B,SAAS,QAAAA,aAAY;;;ACArB,SAAS,OAAO,iBAAiB;;;ACAjC,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,OAAO,cAAc;AAErB,IAAM,QAAQ,SAAS,cAAc,EAAE,QAAQ,GAAG,CAAC;AAE5C,SAAS,eAAuB;AACrC,SAAO,MAAM;AACf;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,aAAa,GAAG,aAAa;AAC3C;AAEO,SAAS,aAAa,cAAsB,QAAQ,IAAI,GAAW;AACxE,SAAO,KAAK,aAAa,SAAS;AACpC;AAEO,SAAS,iBAAiB,cAAsB,QAAQ,IAAI,GAAW;AAC5E,SAAO,KAAK,aAAa,aAAa;AACxC;AAEO,SAAS,gBAAgB,cAAsB,QAAQ,IAAI,GAAW;AAC3E,SAAO,KAAK,iBAAiB,WAAW,GAAG,eAAe;AAC5D;AAEO,SAAS,aAAqB;AACnC,SAAO,QAAQ;AACjB;AAEO,SAAS,YAAY,MAAsB;AAChD,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,WAAO,KAAK,WAAW,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,EACzC;AACA,SAAO;AACT;;;ACnCA,SAAS,YAAY,iBAAiB;AACtC,SAAS,UAAU,WAAW,YAAY,YAAY,SAAS,QAAQ,UAAU;AACjF,SAAS,SAAe,gBAAgB;AAEjC,SAAS,UAAU,SAAuB;AAC/C,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EACxC;AACF;AAEO,SAAS,WAAW,UAA2B;AACpD,SAAO,WAAW,QAAQ;AAC5B;AAEA,eAAsB,aAAa,UAAmC;AACpE,SAAO,MAAM,SAAS,UAAU,OAAO;AACzC;AAEA,eAAsB,cAAc,UAAkB,SAAgC;AACpF,YAAU,QAAQ,QAAQ,CAAC;AAC3B,QAAM,UAAU,UAAU,SAAS,OAAO;AAC5C;AAEA,eAAsB,SAAS,QAAgB,MAA6B;AAC1E,YAAU,QAAQ,IAAI,CAAC;AACvB,QAAM,WAAW,QAAQ,IAAI;AAC/B;AAEA,eAAsB,WAAW,UAAiC;AAChE,MAAI,WAAW,QAAQ,GAAG;AACxB,UAAM,OAAO,QAAQ;AAAA,EACvB;AACF;AAQA,eAAsB,UAAU,SAAiB,WAAuC;AACtF,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,MAAM,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AAC9D,MAAI,QAAQ,QACT,OAAO,WAAS,MAAM,OAAO,CAAC,EAC9B,IAAI,WAAS,MAAM,IAAI;AAE1B,MAAI,WAAW;AACb,YAAQ,MAAM,OAAO,UAAQ,KAAK,SAAS,SAAS,CAAC;AAAA,EACvD;AAEA,SAAO;AACT;AAEO,SAAS,YAAY,UAA0B;AAEpD,SAAO,SAAS,UAAU,KAAK;AACjC;AAEO,SAAS,gBAAgB,UAA0B;AAGxD,QAAM,WAAW,SAAS,YAAY,EAAE,SAAS,KAAK,IAClD,SAAS,MAAM,GAAG,EAAE,IACpB;AACJ,SAAO,GAAG,QAAQ;AACpB;AAEO,SAAS,kBAAkB,UAA0B;AAE1D,QAAM,OAAO,SAAS,YAAY,EAAE,SAAS,KAAK,IAC9C,SAAS,MAAM,GAAG,EAAE,IACpB;AACJ,SAAO,KAAK,YAAY;AAC1B;AAEO,SAAS,cACd,OACA,gBACe;AAEf,QAAM,kBAAkB,kBAAkB,KAAK;AAG/C,QAAM,QAAQ,eAAe;AAAA,IAC3B,UAAQ,kBAAkB,IAAI,MAAM;AAAA,EACtC;AAEA,SAAO,SAAS;AAClB;;;ACjEO,IAAM,iBAA+B;AAAA,EAC1C,SAAS;AAAA,EACT,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,UAAU;AAAA,IACV,eAAe;AAAA,EACjB;AACF;;;ACpBO,IAAM,mBAAoC;AAAA,EAC/C,SAAS;AAAA,EACT,OAAO,CAAC;AACV;;;AJdA,eAAsB,aAA2C;AAC/D,QAAM,aAAa,cAAc;AAEjC,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,aAAa,UAAU;AAC7C,QAAM,SAAS,MAAM,OAAO;AAE5B,SAAO;AACT;AAEA,eAAsB,WAAW,QAAqC;AACpE,QAAM,aAAa,cAAc;AACjC,YAAU,aAAa,CAAC;AAExB,QAAM,UAAU,UAAU,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC/C,QAAM,cAAc,YAAY,OAAO;AACzC;AAEA,eAAsB,eAAiC;AACrD,SAAO,WAAW,cAAc,CAAC;AACnC;AAEO,SAAS,aAAa,SAOZ;AACf,QAAM,SAAuB;AAAA,IAC3B,GAAG;AAAA,IACH,QAAQ;AAAA,MACN,MAAM,QAAQ;AAAA,MACd,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,IAClB;AAAA,IACA,UAAU;AAAA,MACR,UAAU,QAAQ,YAAY;AAAA,MAC9B,eAAe,QAAQ,iBAAiB;AAAA,IAC1C;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO;AACjB,WAAO,WAAW,EAAE,OAAO,QAAQ,MAAM;AAAA,EAC3C;AAEA,SAAO;AACT;AAEA,eAAsB,uBAAsC;AAC1D,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,QAAQ;AACV,WAAO,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY;AAClD,UAAM,WAAW,MAAM;AAAA,EACzB;AACF;;;AKjEA,SAAS,SAAAC,QAAO,aAAAC,kBAAiB;AAMjC,eAAsB,aAAa,cAAsB,QAAQ,IAAI,GAAoC;AACvG,QAAM,eAAe,gBAAgB,WAAW;AAEhD,MAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,aAAa,YAAY;AAC/C,QAAM,WAAWC,OAAM,OAAO;AAE9B,SAAO;AACT;AAEA,eAAsB,aAAa,UAA2B,cAAsB,QAAQ,IAAI,GAAkB;AAChH,QAAM,eAAe,gBAAgB,WAAW;AAChD,YAAU,iBAAiB,WAAW,CAAC;AAEvC,QAAM,UAAUC,WAAU,UAAU,EAAE,QAAQ,EAAE,CAAC;AACjD,QAAM,cAAc,cAAc,OAAO;AAC3C;AAMA,eAAsB,oBAAoB,cAAsB,QAAQ,IAAI,GAA6B;AACvG,QAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,SAAO,YAAY,EAAE,GAAG,iBAAiB;AAC3C;AAEO,SAAS,gBAAgB,SAKlB;AACZ,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEO,SAAS,gBAAgB,OAAkB,SAAwC;AACxF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AAuBA,eAAsB,qBACpB,UACA,SACA,cAAsB,QAAQ,IAAI,GACnB;AACf,QAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,MAAI,YAAY,SAAS,MAAM,QAAQ,GAAG;AACxC,aAAS,MAAM,QAAQ,IAAI,gBAAgB,SAAS,MAAM,QAAQ,GAAG,OAAO;AAC5E,UAAM,aAAa,UAAU,WAAW;AAAA,EAC1C;AACF;;;AC5FA,SAAS,QAAAC,aAAY;;;ACArB,SAAS,kBAAkB;AAC3B,SAAS,YAAAC,iBAAgB;AAEzB,eAAsB,SAAS,UAAmC;AAChE,QAAM,UAAU,MAAMA,UAAS,QAAQ;AACvC,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAC9D,SAAO,UAAU,IAAI;AACvB;;;ADKA,IAAM,gBAAgB,CAAC,WAAW;AAElC,eAAsB,kBAAkB,QAAgD;AACtF,QAAM,aAAa,OAAO,OAAO;AAEjC,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAQ,MAAM,UAAU,YAAY,KAAK;AAC/C,QAAM,gBAAgB,MAAM,OAAO,UAAQ,CAAC,cAAc,SAAS,KAAK,YAAY,CAAC,CAAC;AAEtF,SAAO,cAAc,IAAI,WAAS;AAAA,IAChC,MAAM,YAAY,IAAI;AAAA,IACtB;AAAA,IACA,MAAMC,MAAK,YAAY,IAAI;AAAA,EAC7B,EAAE;AACJ;AAEA,eAAsB,kBAAkB,UAAkB,QAA8C;AACtG,QAAM,WAAW,gBAAgB,QAAQ;AACzC,QAAM,WAAWA,MAAK,OAAO,OAAO,MAAM,QAAQ;AAElD,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAwBO,SAAS,SAAS,KAAsB;AAC7C,SACE,IAAI,WAAW,MAAM,KACrB,IAAI,WAAW,oBAAoB,KACnC,IAAI,WAAW,oBAAoB,KACnC,IAAI,WAAW,uBAAuB,KACtC,IAAI,SAAS,MAAM;AAEvB;;;AExEA,OAAO,eAA8B;AAErC,SAAS,QAAAC,aAAY;AAGd,SAAS,UAAU,MAAuB;AAC/C,SAAO,WAAWA,MAAK,MAAM,MAAM,CAAC;AACtC;AAEA,eAAsB,UAAU,KAAa,YAAmC;AAC9E,QAAM,MAAM,UAAU;AACtB,QAAM,IAAI,MAAM,KAAK,UAAU;AACjC;AAEA,eAAsB,SAAS,MAA6B;AAC1D,QAAM,MAAM,UAAU,IAAI;AAC1B,QAAM,IAAI,KAAK;AACjB;AAEA,eAAsB,UAAU,MAAgC;AAC9D,MAAI,CAAC,UAAU,IAAI,EAAG,QAAO;AAE7B,QAAM,MAAM,UAAU,IAAI;AAC1B,MAAI;AACF,UAAM,UAAU,MAAM,IAAI,WAAW;AACrC,WAAO,QAAQ,SAAS;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,MAAsC;AA/BzE;AAgCE,MAAI,CAAC,UAAU,IAAI,EAAG,QAAO;AAE7B,QAAM,MAAM,UAAU,IAAI;AAC1B,MAAI;AACF,UAAM,UAAU,MAAM,IAAI,WAAW,IAAI;AACzC,UAAM,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,QAAQ;AACpD,aAAO,sCAAQ,SAAR,mBAAc,UAAS;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,QAA+B;AAClE,MAAI,CAAC,OAAO,SAAS,SAAU,QAAO;AACtC,MAAI,OAAO,SAAS,kBAAkB,QAAS,QAAO;AACtD,MAAI,CAAC,OAAO,SAAS,SAAU,QAAO;AAEtC,QAAM,WAAW,IAAI,KAAK,OAAO,SAAS,QAAQ;AAClD,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,sBAAsB,IAAI,QAAQ,IAAI,SAAS,QAAQ,MAAM,MAAO,KAAK;AAE/E,UAAQ,OAAO,SAAS,eAAe;AAAA,IACrC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,sBAAsB;AAAA,IAC/B,KAAK;AACH,aAAO,sBAAsB;AAAA,IAC/B;AACE,aAAO;AAAA,EACX;AACF;AAEA,eAAsB,mBAAmB,QAAoE;AAC3G,QAAM,aAAa,OAAO,OAAO;AAEjC,MAAI,CAAC,UAAU,UAAU,GAAG;AAC1B,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAEA,MAAI,CAAC,qBAAqB,MAAM,GAAG;AACjC,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAEA,MAAI,CAAE,MAAM,UAAU,UAAU,GAAI;AAClC,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AAEA,MAAI;AACF,UAAM,SAAS,UAAU;AACzB,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO,EAAE,QAAQ,OAAO,OAAO,QAAQ;AAAA,EACzC;AACF;;;ACrFO,SAAS,YAAqB;AACnC,SAAO,QAAQ,aAAa;AAC9B;AAUO,SAAS,QAAiB;AAE/B,MAAI,QAAQ,aAAa,QAAS,QAAO;AAGzC,SAAO,CAAC,EAAE,QAAQ,IAAI,mBAAmB,QAAQ,IAAI;AACvD;AAEO,SAAS,qBAA0C;AAExD,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,EAAG,QAAO;AAIzB,MAAI,QAAQ,IAAI,SAAS;AACvB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACrCA,OAAO,QAAQ;AAGR,SAAS,iBAAiBC,SAA4B;AAC3D,UAAQA,SAAQ;AAAA,IACd,KAAK;AACH,aAAO,GAAG,MAAM,QAAG;AAAA,IACrB,KAAK;AACH,aAAO,GAAG,OAAO,QAAG;AAAA,IACtB,KAAK;AACH,aAAO,GAAG,IAAI,QAAG;AAAA,IACnB,KAAK;AACH,aAAO,GAAG,IAAI,QAAG;AAAA,IACnB;AACE,aAAO,GAAG,IAAI,GAAG;AAAA,EACrB;AACF;AAEO,SAAS,qBAAqBA,SAA4B;AAC/D,UAAQA,SAAQ;AAAA,IACd,KAAK;AACH,aAAO,GAAG,MAAM,QAAQ;AAAA,IAC1B,KAAK;AACH,aAAO,GAAG,OAAO,UAAU;AAAA,IAC7B,KAAK;AACH,aAAO,GAAG,IAAI,UAAU;AAAA,IAC1B,KAAK;AACH,aAAO,GAAG,IAAI,UAAU;AAAA,IAC1B;AACE,aAAO,GAAG,IAAI,SAAS;AAAA,EAC3B;AACF;AAEO,SAAS,eAAe,MAAcA,SAAoB,SAA0B;AACzF,QAAM,OAAO,iBAAiBA,OAAM;AACpC,QAAM,aAAa,qBAAqBA,OAAM;AAC9C,QAAM,cAAc,UAAU,GAAG,IAAI,KAAK,OAAO,GAAG,IAAI;AAExD,SAAO,KAAK,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,IAAI,UAAU,GAAG,WAAW;AACjE;AAsBO,SAAS,WAAW,MAAsB;AAC/C,SAAO,GAAG,KAAK,IAAI;AACrB;AAEO,SAAS,cAAc,SAAyB;AACrD,SAAO,GAAG,KAAK,KAAK,OAAO,IAAI;AACjC;AAEO,SAAS,aAAaC,OAAsB;AACjD,SAAO,GAAG,KAAKA,KAAI;AACrB;AAEO,SAAS,cAAc,MAAsB;AAClD,SAAO,GAAG,MAAM,KAAK,IAAI,EAAE;AAC7B;AAEO,SAAS,iBAAiB,MAAsB;AACrD,SAAO,GAAG,IAAI,KAAK,IAAI,EAAE;AAC3B;AAEO,SAAS,kBAAkB,MAAsB;AACtD,SAAO,GAAG,IAAI,KAAK,IAAI,EAAE;AAC3B;AAEO,SAAS,iBAAiB,MAAsB;AACrD,SAAO,GAAG,KAAK,IAAI;AACrB;;;ACvFA,OAAOC,SAAQ;AAGR,IAAM,WAAW;AAAA;AAAA,EAEtB,eAAe,qCAAqC,cAAc,SAAS,CAAC;AAAA,EAC5E,YAAY,qCAAqC,cAAc,QAAQ,CAAC;AAAA,EACxE,aAAa;AAAA;AAAA,EAGb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,mBAAmB;AAAA;AAAA,EAGnB,gBAAgB,CAAC,SAAiB,+BAA+B,WAAW,IAAI,CAAC;AAAA,EACjF,eAAe;AAAA,EACf,eAAe,CAAC,SAAiB,sBAAsB,WAAW,IAAI,CAAC;AAAA;AAAA,EAGvE,YAAY,CAAC,UAAkB,SAAS,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EAC3E,aAAa,CAAC,UACZ;AAAA,EAAmD,MAAM,IAAI,OAAK,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,EAC1F,YAAY;AAAA,EACZ,cAAc,CAAC,SAAiB,SAAS,IAAI;AAAA;AAAA,EAG7C,eAAe,CAAC,UAAkB,WAAW,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EAChF,oBAAoB,CAAC,SAAiB,SAAS,IAAI;AAAA;AAAA,EAGnD,iBAAiB;AAAA,EACjB,sBAAsB,CAAC,UACrB,GAAG,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE,QAAQ,UAAU,IAAI,MAAM,EAAE,mBAAmB,cAAc,SAAS,CAAC;AAAA,EACjH,eAAeC,IAAG,IAAI,+CAA0C;AAAA;AAAA,EAGhE,aAAa,CAAC,UAAkB,GAAG,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EACtE,aAAa,CAAC,UAAkB,GAAG,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EACtE,cAAc,CAAC,UAAkB,GAAG,KAAK,QAAQ,UAAU,IAAI,MAAM,EAAE;AAAA,EACvE,cAAc;AAAA,EACd,cAAc,CAAC,SAAiB,GAAG,IAAI;AAAA,EACvC,yBAAyB,CAAC,SAAiB,GAAG,IAAI;AAAA;AAAA,EAGlD,eAAe,CAAC,SAAiB,SAAS,IAAI;AAAA,EAC9C,eAAe,CAAC,SAAiB,SAAS,IAAI;AAAA,EAC9C,eAAe,CAAC,SAAiB,SAAS,IAAI;AAAA,EAC9C,eAAe,CAAC,SAAiB,SAAS,IAAI;AAAA;AAAA,EAG9C,kBAAkB,CAAC,SAAiB,4BAA4B,IAAI;AAAA,EACpE,aAAa;AAAA;AAAA,EAGb,eAAe;AAAA,EACf,mBAAmB,CAAC,UAAkB,GAAG,KAAK,SAAS,UAAU,IAAI,MAAM,EAAE;AAAA;AAAA,EAG7E,cAAc,CAAC,QAAgB,UAAU,GAAG;AAAA,EAC5C,oBAAoB,CAAC,SAAiB,oBAAoB,IAAI;AAAA,EAC9D,mBAAmB,CAAC,SAAiB,mBAAmB,IAAI;AAC9D;;;AC9DA,YAAY,OAAO;AACnB,OAAOC,SAAQ;AAQR,SAASC,UAAS,OAAyB;AAChD,SAAS,WAAS,KAAK;AACzB;AAUA,eAAsB,mBAAiD;AACrE,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,SAAS,OAAO,gBAAgB,MAAM,2CAA2C;AAAA,MAC1F,EAAE,OAAO,OAAO,OAAO,kBAAkB,MAAM,qBAAqB;AAAA,IACtE;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,kBAA4C;AAChE,SAAO,MAAQ,OAAK;AAAA,IAClB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,cAAwC;AAC5D,SAAO,MAAQ,OAAK;AAAA,IAClB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,iBAA2C;AAC/D,SAAO,MAAQ,OAAK;AAAA,IAClB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,sBAAuD;AAC3E,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,SAAS,OAAO,SAAS,MAAM,cAAc;AAAA,MACtD,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,gBAAgB;AAAA,MAC1D,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,MACnC,EAAE,OAAO,SAAS,OAAO,SAAS,MAAM,cAAc;AAAA,IACxD;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,qBAAqD;AACzE,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,YAAY,OAAO,4BAA4B;AAAA,MACxD,EAAE,OAAO,WAAW,OAAO,WAAW;AAAA,MACtC,EAAE,OAAO,OAAO,OAAO,oCAAoC;AAAA,IAC7D;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,iBAAiB,WAAqB,WAAiD;AAC3G,QAAM,UAAU,UAAU,IAAI,WAAS;AAAA,IACrC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM,UAAU,SAAS,IAAI,IAAI,sBAAsB;AAAA,EACzD,EAAE;AAEF,SAAO,MAAQ,cAAY;AAAA,IACzB,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,EACZ,CAAC;AACH;AAEA,eAAsB,mBACpB,UACA,mBACA,cACoC;AACpC,QAAM,UAAU,oBACZ,GAAG,QAAQ,sDACX,GAAG,QAAQ;AAEf,EAAE,MAAI,KAAK,OAAO;AAElB,QAAM,UAAsE;AAAA,IAC1E;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,mBAAmB;AACrB,YAAQ,KAAK;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,UAAQ;AAAA,IACN,eACI,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,uBAAuB,IACjE,EAAE,OAAO,QAAQ,OAAO,QAAQ,MAAM,qBAAqB;AAAA,EACjE;AAEA,QAAM,SAAS,MAAQ,SAAO;AAAA,IAC5B,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAM,WAAS,MAAM,GAAG;AACtB,WAAO,eAAe,WAAW;AAAA,EACnC;AAEA,SAAO;AACT;AAEA,eAAsB,oBAAoB,UAAyD;AACjG,EAAE,MAAI,KAAK,GAAG,QAAQ,oCAAoC;AAE1D,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,QAAQ,OAAO,cAAc,MAAM,iCAAiC;AAAA,MAC7E,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,mCAAmC;AAAA,IAC/E;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,mBAAmB,UAAwD;AAC/F,EAAE,MAAI,KAAK,GAAG,QAAQ,0BAA0B;AAEhD,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,WAAW,OAAO,WAAW,MAAM,mBAAmB;AAAA,MAC/D,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,uBAAuB;AAAA,IACnE;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,oBAAoB,UAAkD;AAC1F,EAAE,MAAI,KAAK,GAAG,QAAQ,iCAAiC;AAEvD,SAAO,MAAQ,SAAO;AAAA,IACpB,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,aAAa,OAAO,mBAAmB,MAAM,8BAA8B;AAAA,MACpF,EAAE,OAAO,QAAQ,OAAO,cAAc,MAAM,wDAAwD;AAAA,MACpG,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,gBAAgB;AAAA,IAC5D;AAAA,EACF,CAAC;AACH;AAEO,SAASC,WAAU;AACxB,SAAS,UAAQ;AACnB;AAEO,SAASC,OAAM,SAAiB;AACrC,EAAE,QAAMC,IAAG,OAAOA,IAAG,MAAM,IAAI,OAAO,GAAG,CAAC,CAAC;AAC7C;AAEO,SAASC,OAAM,SAAiB;AACrC,EAAE,QAAM,OAAO;AACjB;AAEO,IAAMC,OAAQ;;;AbtKrB,eAAsB,KAAK,UAAuB,CAAC,GAAkB;AACnE,EAAAC,OAAM,SAAS,WAAW;AAG1B,MAAI,CAAC,QAAQ,SAAS,MAAM,aAAa,GAAG;AAC1C,IAAAC,KAAI,KAAK,SAAS,iBAAiB;AACnC;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,iBAAiB;AAC1C,MAAIC,UAAS,UAAU,GAAG;AACxB,IAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI,qBAAiC;AAErC,MAAI,eAAe,OAAO;AAExB,WAAO,MAAM;AACX,YAAM,SAAS,MAAM,YAAY;AACjC,UAAIC,UAAS,MAAM,GAAG;AACpB,QAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,MACF;AAEA,YAAM,YAAY,MAAM,eAAe;AACvC,UAAIC,UAAS,SAAS,GAAG;AACvB,QAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,MACF;AAEA,YAAM,oBAAoB,YAAY,SAAmB;AAEzD,YAAM,IAAIE,SAAQ;AAClB,QAAE,MAAM,uBAAuB;AAE/B,UAAI;AACF,kBAAUC,MAAK,mBAAmB,IAAI,CAAC;AACvC,cAAM,UAAU,QAAkB,iBAAiB;AACnD,UAAE,KAAK,iCAAiC;AACxC,qBAAa;AACb,iBAAS;AACT;AAAA,MACF,SAAS,OAAO;AACd,UAAE,KAAK,6BAA6B;AACpC,QAAAH,KAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAChE,QAAAA,KAAI,KAAK,mBAAmB;AAAA,MAC9B;AAAA,IACF;AAAA,EACF,OAAO;AAEL,WAAO,MAAM;AACX,YAAM,YAAY,MAAM,gBAAgB;AACxC,UAAIC,UAAS,SAAS,GAAG;AACvB,QAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,MACF;AAEA,YAAM,eAAe,YAAY,SAAmB;AAEpD,UAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,QAAAA,KAAI,MAAM,SAAS,eAAe,YAAY,CAAC;AAC/C,QAAAA,KAAI,KAAK,mBAAmB;AAC5B;AAAA,MACF;AAEA,mBAAa;AAGb,UAAI,UAAU,YAAY,GAAG;AAC3B,cAAM,iBAAiB,MAAM,aAAa,YAAY;AACtD,YAAI,gBAAgB;AAClB,+BAAqB;AACrB,mBAAS;AACT,UAAAA,KAAI,KAAK,wCAAwC,cAAc,EAAE;AAAA,QACnE;AAAA,MACF;AACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,oBAAoB;AAChD,MAAIC,UAAS,aAAa,GAAG;AAC3B,IAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,EACF;AAGA,MAAI;AACJ,MAAI,UAAU,GAAG;AACf,UAAM,gBAAgB,mBAAmB;AACzC,QAAI,eAAe;AACjB,MAAAA,KAAI,KAAK,mBAAmB,aAAa,EAAE;AAC3C,cAAQ;AAAA,IACV,OAAO;AACL,YAAM,gBAAgB,MAAM,mBAAmB;AAC/C,UAAIC,UAAS,aAAa,GAAG;AAC3B,QAAAD,KAAI,KAAK,kBAAkB;AAC3B;AAAA,MACF;AACA,cAAQ;AAAA,IACV;AAAA,EACF;AAGA,QAAM,SAAS,aAAa;AAAA,IAC1B,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM;AAEvB,EAAAI,OAAM,SAAS,WAAW;AAC5B;;;Ac5JA,SAAS,QAAAC,aAAY;AAiCrB,eAAsB,IAAI,OAAiB,UAAsB,CAAC,GAAkB;AAElF,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,IAAIC,SAAQ;AAClB,IAAE,MAAM,yBAAyB;AACjC,QAAM,aAAa,MAAM,mBAAmB,MAAM;AAClD,MAAI,WAAW,QAAQ;AACrB,UAAM,qBAAqB;AAAA,EAC7B;AACA,IAAE,KAAK,WAAW,QAAQ,SAAS,gBAAgB,uBAAuB;AAG1E,QAAM,iBAAiB,MAAM,kBAAkB,MAAM;AACrD,MAAI,eAAe,WAAW,GAAG;AAC/B,IAAAD,KAAI,MAAM,2BAA2B;AACrC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,QAAM,iBAAiB,WAAW,OAAO,KAAK,SAAS,KAAK,IAAI,CAAC;AAGjE,MAAI;AAEJ,MAAI,QAAQ,KAAK;AACf,iBAAa,eAAe,IAAI,OAAK,EAAE,IAAI;AAAA,EAC7C,WAAW,MAAM,SAAS,GAAG;AAC3B,iBAAa;AAAA,EACf,OAAO;AAEL,UAAM,WAAW,MAAM;AAAA,MACrB,eAAe,IAAI,OAAK,EAAE,IAAI;AAAA,MAC9B;AAAA,IACF;AAEA,QAAIE,UAAS,QAAQ,GAAG;AACtB,MAAAF,KAAI,KAAK,YAAY;AACrB;AAAA,IACF;AAEA,iBAAa;AAAA,EACf;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,IAAAA,KAAI,KAAK,SAAS,UAAU;AAC5B;AAAA,EACF;AAGA,QAAM,qBAAqB,eAAe,IAAI,OAAK,EAAE,IAAI;AACzD,QAAM,gBAA0B,CAAC;AACjC,QAAM,eAAyB,CAAC;AAEhC,aAAW,QAAQ,YAAY;AAC7B,UAAM,QAAQ,cAAc,MAAM,kBAAkB;AACpD,QAAI,OAAO;AACT,oBAAc,KAAK,KAAK;AAAA,IAC1B,OAAO;AACL,mBAAa,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,eAAW,QAAQ,cAAc;AAC/B,MAAAA,KAAI,MAAM,SAAS,aAAa,IAAI,CAAC;AAAA,IACvC;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,aAAa;AAC/B,YAAU,SAAS;AAGnB,QAAM,kBAAkB,MAAM,oBAAoB;AAClD,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,aAAW,QAAQ,eAAe;AAChC,UAAM,aAAa,MAAM,kBAAkB,MAAM,MAAM;AACvD,QAAI,CAAC,WAAY;AAEjB,UAAM,WAAW,gBAAgB,IAAI;AACrC,UAAM,aAAaG,MAAK,WAAW,QAAQ;AAC3C,UAAM,aAAa,MAAM,SAAS,UAAU;AAG5C,QAAI,WAAW,UAAU,GAAG;AAC1B,YAAM,YAAY,MAAM,SAAS,UAAU;AAC3C,YAAM,QAAQ,gBAAgB,MAAM,IAAI;AAGxC,UAAI,SAAS,cAAc,MAAM,WAAW;AAC1C,cAAM,SAAS,YAAY,UAAU;AACrC,cAAM,UAAU,MAAM,SAAS,UAAU;AACzC,wBAAgB,MAAM,IAAI,IAAI,gBAAgB;AAAA,UAC5C,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,WAAW;AAAA,QACb,CAAC;AACD,QAAAH,KAAI,QAAQ,WAAW,QAAQ,EAAE;AACjC;AACA;AAAA,MACF;AAGA,UAAI,CAAC,SAAS,cAAc,MAAM,WAAW;AAC3C,cAAM,SAAS,MAAM,mBAAmB,MAAM,OAAO,KAAK;AAE1D,YAAIE,UAAS,MAAM,KAAK,WAAW,QAAQ;AACzC;AACA;AAAA,QACF;AAEA,YAAI,WAAW,UAAU;AAEvB,0BAAgB,MAAM,IAAI,IAAI,gBAAgB;AAAA,YAC5C,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,UACV,CAAC;AACD,0BAAgB,MAAM,IAAI,EAAE,cAAa,oBAAI,KAAK,GAAE,YAAY;AAChE,UAAAF,KAAI,KAAK,GAAG,QAAQ,mBAAmB;AACvC;AAAA,QACF;AAAA,MAGF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,YAAY,UAAU;AACrC,YAAM,OAAO,MAAM,SAAS,UAAU;AAEtC,sBAAgB,MAAM,IAAI,IAAI,gBAAgB;AAAA,QAC5C,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,WAAW;AAAA,MACb,CAAC;AAED,MAAAA,KAAI,QAAQ,SAAS,QAAQ,EAAE;AAC/B;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,KAAI,MAAM,iBAAiB,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IAClG;AAAA,EACF;AAEA,QAAM,aAAa,eAAe;AAElC,MAAI,aAAa,GAAG;AAClB,IAAAA,KAAI,KAAK,SAAS,WAAW,UAAU,CAAC;AAAA,EAC1C;AACA,MAAI,eAAe,GAAG;AACpB,IAAAA,KAAI,KAAK,GAAG,YAAY,mBAAmB;AAAA,EAC7C;AACF;;;ACnMA,SAAS,QAAAI,aAAY;AAiBrB,eAAsB,OAAO,OAAiB,UAAyB,CAAC,GAAkB;AAExF,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,IAAAA,KAAI,MAAM,qBAAqB;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,aAAa;AAC/B,QAAM,gBAAgB,OAAO,KAAK,SAAS,KAAK;AAChD,MAAI,eAAe;AAEnB,aAAW,QAAQ,OAAO;AAExB,UAAM,QAAQ,cAAc,MAAM,aAAa;AAC/C,QAAI,CAAC,OAAO;AACV,MAAAA,KAAI,KAAK,SAAS,mBAAmB,IAAI,CAAC;AAC1C;AAAA,IACF;AAEA,UAAM,WAAW,gBAAgB,KAAK;AACtC,UAAM,aAAaC,MAAK,WAAW,QAAQ;AAG3C,QAAI,CAAC,QAAQ,UAAU;AACrB,UAAI;AACF,cAAM,WAAW,UAAU;AAAA,MAC7B,SAAS,OAAO;AACd,QAAAD,KAAI,KAAK,oBAAoB,QAAQ,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,MACpG;AAAA,IACF;AAGA,WAAO,SAAS,MAAM,KAAK;AAC3B,IAAAA,KAAI,QAAQ,WAAW,KAAK,EAAE;AAC9B;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ;AAE3B,MAAI,eAAe,GAAG;AACpB,IAAAA,KAAI,KAAK,SAAS,cAAc,YAAY,CAAC;AAAA,EAC/C;AACF;;;ACxEA,SAAS,QAAAE,aAAY;AAerB,eAAsB,SAAwB;AAE5C,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,IAAIC,SAAQ;AAClB,IAAE,MAAM,yBAAyB;AACjC,QAAM,aAAa,MAAM,mBAAmB,MAAM;AAClD,MAAI,WAAW,QAAQ;AACrB,UAAM,qBAAqB;AAAA,EAC7B;AACA,IAAE,KAAK,EAAE;AAET,MAAI,WAAW,OAAO;AACpB,IAAAD,KAAI,KAAK,SAAS,aAAa;AAAA,EACjC;AAEA,QAAM,YAAY,OAAO,KAAK,SAAS,KAAK;AAC5C,MAAI,UAAU,WAAW,GAAG;AAC1B,IAAAA,KAAI,KAAK,qBAAqB;AAC9B;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,mBAAmB,CAAC;AAC7C,UAAQ,IAAI,EAAE;AAEd,QAAM,YAAY,aAAa;AAC/B,MAAI,iBAAiB;AAErB,aAAW,YAAY,UAAU,KAAK,GAAG;AACvC,UAAM,QAAQ,SAAS,MAAM,QAAQ;AACrC,UAAM,WAAW,gBAAgB,QAAQ;AACzC,UAAM,YAAYE,MAAK,WAAW,QAAQ;AAC1C,UAAM,aAAaA,MAAK,OAAO,OAAO,MAAM,QAAQ;AAEpD,UAAM,SAAS,MAAM,gBAAgB,OAAO,WAAW,UAAU;AACjE,QAAI;AAEJ,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK;AACH,kBAAU;AACV;AACA;AAAA,MACF,KAAK;AACH,kBAAU;AACV;AACA;AAAA,MACF,KAAK;AACH;AAAA,MACF,KAAK;AACH;AAAA,IACJ;AAEA,QAAI,CAAC,OAAO,aAAa;AACvB,gBAAU;AACV;AAAA,IACF,WAAW,CAAC,OAAO,cAAc;AAC/B,gBAAU;AACV;AAAA,IACF;AAEA,YAAQ,IAAI,eAAe,WAAW,OAAO,OAAO,QAAQ,OAAO,CAAC;AAAA,EACtE;AAEA,UAAQ,IAAI,EAAE;AAEd,MAAI,iBAAiB,GAAG;AACtB,IAAAF,KAAI,KAAK,SAAS,qBAAqB,cAAc,CAAC;AAAA,EACxD,OAAO;AACL,IAAAA,KAAI,QAAQ,SAAS,eAAe;AAAA,EACtC;AACF;AAEA,eAAe,gBACb,OACA,WACA,YAC4B;AAC5B,QAAM,cAAc,WAAW,SAAS;AACxC,QAAM,eAAe,WAAW,UAAU;AAG1C,MAAI,MAAM,WAAW,YAAY;AAC/B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,eAAe;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,eAAe,CAAC,cAAc;AACjC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,cAAc,CAAC;AAAA,MACf,eAAe,CAAC;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAmB,MAAM,SAAS,SAAS;AACjD,QAAM,oBAAoB,MAAM,SAAS,UAAU;AAEnD,QAAM,eAAe,qBAAqB,MAAM;AAChD,QAAM,gBAAgB,sBAAsB,MAAM;AAElD,MAAIG;AAEJ,MAAI,cAAc;AAChB,IAAAA,UAAS;AAAA,EACX,WAAW,eAAe;AACxB,IAAAA,UAAS;AAAA,EACX,OAAO;AACL,IAAAA,UAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL,QAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC5JA,SAAS,QAAAC,cAAY;;;ACArB,SAAS,QAAAC,aAAY;AA0BrB,eAAsB,KAAK,OAAiB,UAAuB,CAAC,GAAkB;AAEpF,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,aAAa;AAG/B,MAAI;AAEJ,MAAI,QAAQ,KAAK;AAEf,kBAAc,CAAC;AACf,eAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG;AAC9D,UAAI,MAAM,WAAW,WAAY;AAEjC,YAAM,WAAW,gBAAgB,QAAQ;AACzC,YAAM,YAAYC,MAAK,WAAW,QAAQ;AAE1C,UAAI,CAAC,WAAW,SAAS,EAAG;AAE5B,YAAM,mBAAmB,MAAM,SAAS,SAAS;AACjD,UAAI,qBAAqB,MAAM,WAAW;AACxC,oBAAY,KAAK,QAAQ;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,YAAY,WAAW,GAAG;AAC5B,MAAAD,KAAI,KAAK,SAAS,WAAW;AAC7B;AAAA,IACF;AAAA,EACF,WAAW,MAAM,SAAS,GAAG;AAE3B,UAAM,gBAAgB,OAAO,KAAK,SAAS,KAAK;AAChD,kBAAc,CAAC;AACf,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,cAAc,MAAM,aAAa;AAC/C,UAAI,OAAO;AACT,oBAAY,KAAK,KAAK;AAAA,MACxB,OAAO;AACL,QAAAA,KAAI,KAAK,SAAS,IAAI,yBAAyB;AAAA,MACjD;AAAA,IACF;AAAA,EACF,OAAO;AACL,IAAAA,KAAI,MAAM,6DAA6D;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,aAAW,YAAY,aAAa;AAClC,UAAM,QAAQ,SAAS,MAAM,QAAQ;AACrC,QAAI,CAAC,MAAO;AAEZ,UAAM,WAAW,gBAAgB,QAAQ;AACzC,UAAM,YAAYC,MAAK,WAAW,QAAQ;AAC1C,UAAM,aAAaA,MAAK,OAAO,OAAO,MAAM,QAAQ;AAEpD,UAAM,aAAa,UAAU,YAAY,SAAS;AAAA,EACpD;AACF;AAEA,eAAsB,SAAS,OAAgC;AAC7D,SAAO,KAAK,OAAO,CAAC,CAAC;AACvB;AAEA,eAAe,aACb,UACA,YACA,WACe;AACf,QAAM,eAAe,WAAW,UAAU;AAC1C,QAAM,cAAc,WAAW,SAAS;AAExC,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,aAAa,QAAQ,KAAK,CAAC;AACpD,UAAQ,IAAI,EAAE;AAEd,MAAI,CAAC,gBAAgB,CAAC,aAAa;AACjC,IAAAD,KAAI,KAAK,yCAAyC;AAClD;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,IAAAA,KAAI,KAAK,8BAA8B;AACvC,YAAQ,IAAI,iBAAiB,sBAAsB,CAAC;AACpD,YAAQ,IAAI,iBAAiB,cAAc,WAAW,SAAS,CAAC,GAAG,CAAC;AACpE;AAAA,EACF;AAEA,MAAI,CAAC,aAAa;AAChB,IAAAA,KAAI,KAAK,uBAAuB;AAChC,YAAQ,IAAI,iBAAiB,eAAe,WAAW,UAAU,CAAC,GAAG,CAAC;AACtE,YAAQ,IAAI,iBAAiB,qBAAqB,CAAC;AACnD;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM,aAAa,UAAU;AACnD,QAAM,eAAe,MAAM,aAAa,SAAS;AAEjD,MAAI,kBAAkB,cAAc;AAClC,IAAAA,KAAI,KAAK,SAAS,iBAAiB,QAAQ,CAAC;AAC5C;AAAA,EACF;AAEA,UAAQ,IAAI,iBAAiB,eAAe,UAAU,GAAG,CAAC;AAC1D,UAAQ,IAAI,iBAAiB,cAAc,SAAS,GAAG,CAAC;AACxD,UAAQ,IAAI,EAAE;AAGd,QAAM,cAAc,cAAc,MAAM,IAAI;AAC5C,QAAM,aAAa,aAAa,MAAM,IAAI;AAE1C,QAAME,QAAO,kBAAkB,aAAa,UAAU;AAEtD,aAAW,QAAQA,OAAM;AACvB,QAAI,KAAK,SAAS,OAAO;AACvB,cAAQ,IAAI,cAAc,KAAK,OAAO,CAAC;AAAA,IACzC,WAAW,KAAK,SAAS,UAAU;AACjC,cAAQ,IAAI,iBAAiB,KAAK,OAAO,CAAC;AAAA,IAC5C,OAAO;AACL,cAAQ,IAAI,kBAAkB,KAAK,OAAO,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AAChB;AAOA,SAAS,kBAAkB,QAAkB,OAA6B;AAExE,QAAM,SAAqB,CAAC;AAC5B,QAAM,SAAS,KAAK,IAAI,OAAO,QAAQ,MAAM,MAAM;AAGnD,QAAMC,aAAY,IAAI,IAAI,MAAM;AAChC,QAAM,WAAW,IAAI,IAAI,KAAK;AAE9B,MAAI,KAAK;AACT,MAAI,KAAK;AAET,SAAO,KAAK,OAAO,UAAU,KAAK,MAAM,QAAQ;AAC9C,QAAI,MAAM,OAAO,QAAQ;AAEvB,aAAO,KAAK,EAAE,MAAM,OAAO,SAAS,MAAM,EAAE,EAAE,CAAC;AAC/C;AAAA,IACF,WAAW,MAAM,MAAM,QAAQ;AAE7B,aAAO,KAAK,EAAE,MAAM,UAAU,SAAS,OAAO,EAAE,EAAE,CAAC;AACnD;AAAA,IACF,WAAW,OAAO,EAAE,MAAM,MAAM,EAAE,GAAG;AAEnC,aAAO,KAAK,EAAE,MAAM,WAAW,SAAS,OAAO,EAAE,EAAE,CAAC;AACpD;AACA;AAAA,IACF,WAAW,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC,GAAG;AAEpC,aAAO,KAAK,EAAE,MAAM,UAAU,SAAS,OAAO,EAAE,EAAE,CAAC;AACnD;AAAA,IACF,WAAW,CAACA,WAAU,IAAI,MAAM,EAAE,CAAC,GAAG;AAEpC,aAAO,KAAK,EAAE,MAAM,OAAO,SAAS,MAAM,EAAE,EAAE,CAAC;AAC/C;AAAA,IACF,OAAO;AAEL,aAAO,KAAK,EAAE,MAAM,UAAU,SAAS,OAAO,EAAE,EAAE,CAAC;AACnD,aAAO,KAAK,EAAE,MAAM,OAAO,SAAS,MAAM,EAAE,EAAE,CAAC;AAC/C;AACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADnLA,eAAsB,KAAK,OAAiB,UAAuB,CAAC,GAAkB;AAEpF,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,IAAIC,SAAQ;AAClB,IAAE,MAAM,yBAAyB;AACjC,QAAM,aAAa,MAAM,mBAAmB,MAAM;AAClD,MAAI,WAAW,QAAQ;AACrB,UAAM,qBAAqB;AAAA,EAC7B;AACA,IAAE,KAAK,EAAE;AAET,MAAI,WAAW,OAAO;AACpB,IAAAD,KAAI,KAAK,SAAS,aAAa;AAAA,EACjC;AAGA,QAAM,gBAAgB,OAAO,KAAK,SAAS,KAAK;AAChD,MAAI;AAEJ,MAAI,MAAM,SAAS,GAAG;AACpB,qBAAiB,CAAC;AAClB,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,cAAc,MAAM,aAAa;AAC/C,UAAI,OAAO;AACT,uBAAe,KAAK,KAAK;AAAA,MAC3B,OAAO;AACL,QAAAA,KAAI,KAAK,SAAS,IAAI,yBAAyB;AAAA,MACjD;AAAA,IACF;AAAA,EACF,OAAO;AACL,qBAAiB;AAAA,EACnB;AAEA,QAAM,UAAU;AAAA,IACd,SAAS,CAAC;AAAA,IACV,SAAS,CAAC;AAAA,IACV,UAAU,CAAC;AAAA,IACX,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,YAAY,aAAa;AAC/B,QAAM,eAAe,MAAM,WAAW;AAEtC,aAAW,YAAY,gBAAgB;AACrC,UAAM,QAAQ,SAAS,MAAM,QAAQ;AAErC,QAAI,CAAC,OAAO;AACV,MAAAA,KAAI,KAAK,SAAS,QAAQ,yBAAyB;AACnD,cAAQ,OAAO,KAAK,QAAQ;AAC5B;AAAA,IACF;AAGA,QAAI,MAAM,WAAW,cAAc,CAAC,QAAQ,iBAAiB;AAC3D,MAAAA,KAAI,KAAK,UAAK,QAAQ,0BAA0B;AAChD,cAAQ,QAAQ,KAAK,QAAQ;AAC7B;AAAA,IACF;AAEA,UAAM,WAAW,gBAAgB,QAAQ;AACzC,UAAM,aAAaE,OAAK,OAAO,OAAO,MAAM,QAAQ;AACpD,UAAM,YAAYA,OAAK,WAAW,QAAQ;AAG1C,QAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,YAAM,SAAS,MAAM,oBAAoB,QAAQ;AACjD,UAAIC,UAAS,MAAM,GAAG;AACpB,gBAAQ,QAAQ,KAAK,QAAQ;AAC7B;AAAA,MACF;AAEA,UAAI,WAAW,QAAQ;AACrB,iBAAS,MAAM,QAAQ,IAAI;AAAA,UACzB,GAAG;AAAA,UACH,QAAQ;AAAA,UACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC;AACA,gBAAQ,SAAS,KAAK,QAAQ;AAAA,MAChC,WAAW,WAAW,UAAU;AAC9B,cAAM,WAAW,SAAS;AAC1B,eAAO,SAAS,MAAM,QAAQ;AAC9B,QAAAH,KAAI,QAAQ,WAAW,QAAQ,EAAE;AAAA,MACnC;AACA;AAAA,IACF;AAGA,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAM,SAAS,MAAM,mBAAmB,QAAQ;AAChD,UAAIG,UAAS,MAAM,GAAG;AACpB,gBAAQ,QAAQ,KAAK,QAAQ;AAC7B;AAAA,MACF;AAEA,UAAI,WAAW,WAAW;AACxB,cAAM,SAAS,YAAY,SAAS;AACpC,cAAM,OAAO,MAAM,SAAS,SAAS;AACrC,iBAAS,MAAM,QAAQ,IAAI;AAAA,UACzB,GAAG;AAAA,UACH,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AACA,QAAAH,KAAI,QAAQ,YAAY,QAAQ,KAAK;AACrC,gBAAQ,QAAQ,KAAK,QAAQ;AAAA,MAC/B,WAAW,WAAW,UAAU;AAC9B,eAAO,SAAS,MAAM,QAAQ;AAC9B,QAAAA,KAAI,QAAQ,WAAW,QAAQ,gBAAgB;AAAA,MACjD;AACA;AAAA,IACF;AAGA,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,QAAAA,KAAI,QAAQ,UAAK,QAAQ,aAAa;AACtC,gBAAQ,QAAQ,KAAK,QAAQ;AAC7B;AAAA,MACF,KAAK;AACH,QAAAA,KAAI,KAAK,UAAK,QAAQ,cAAc;AACpC,gBAAQ,SAAS,KAAK,QAAQ;AAC9B;AAAA,MACF,KAAK;AACH,gBAAQ,QAAQ,KAAK,QAAQ;AAC7B;AAAA,MACF,KAAK;AACH,cAAM,aAAa,QAAQ;AAC3B;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ;AAG3B,UAAQ,IAAI,EAAE;AACd,MAAI,QAAQ,QAAQ,SAAS,GAAG;AAC9B,IAAAA,KAAI,QAAQ,SAAS,YAAY,QAAQ,QAAQ,MAAM,CAAC;AAAA,EAC1D;AACA,MAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,IAAAA,KAAI,KAAK,SAAS,aAAa,QAAQ,SAAS,MAAM,CAAC;AAAA,EACzD;AACA,MAAI,QAAQ,OAAO,SAAS,GAAG;AAC7B,IAAAA,KAAI,MAAM,GAAG,QAAQ,OAAO,MAAM,iBAAiB;AAAA,EACrD;AACA,MAAI,QAAQ,QAAQ,WAAW,KAAK,QAAQ,SAAS,WAAW,KAAK,QAAQ,OAAO,WAAW,GAAG;AAChG,IAAAA,KAAI,QAAQ,SAAS,YAAY;AAAA,EACnC;AACF;AAEA,eAAe,SACb,UACA,OACA,YACA,WACA,UACA,SACA,cAC2D;AAE3D,QAAM,mBAAmB,MAAM,SAAS,SAAS;AACjD,QAAM,oBAAoB,MAAM,SAAS,UAAU;AAGnD,QAAM,eAAe,qBAAqB,MAAM;AAChD,QAAM,gBAAgB,sBAAsB,MAAM;AAGlD,MAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,gBAAgB,eAAe;AAClC,UAAM,SAAS,YAAY,SAAS;AACpC,aAAS,MAAM,QAAQ,IAAI;AAAA,MACzB,GAAG;AAAA,MACH,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAGA,MAAI,cAAc;AAEhB,QAAI,QAAQ,OAAO;AACjB,YAAM,SAAS,YAAY,SAAS;AACpC,YAAM,UAAU,MAAM,SAAS,SAAS;AACxC,eAAS,MAAM,QAAQ,IAAI;AAAA,QACzB,GAAG;AAAA,QACH,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AACA,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,MAAM,mBAAmB,UAAU,eAAe,YAAY;AAG3E,WAAO,WAAW,aAAa;AAC7B,YAAM,SAAS,CAAC,QAAQ,CAAC;AACzB,eAAS,MAAM,mBAAmB,UAAU,eAAe,YAAY;AAAA,IACzE;AAEA,QAAIG,UAAS,MAAM,GAAG;AACpB,aAAO,eAAe,cAAc;AAAA,IACtC;AAEA,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,cAAM,SAAS,YAAY,SAAS;AACpC,cAAM,UAAU,MAAM,SAAS,SAAS;AACxC,iBAAS,MAAM,QAAQ,IAAI;AAAA,UACzB,GAAG;AAAA,UACH,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AACA,eAAO;AAAA,MAET,KAAK;AACH,iBAAS,MAAM,QAAQ,IAAI;AAAA,UACzB,GAAG;AAAA,UACH,QAAQ;AAAA,UACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC;AACA,eAAO;AAAA,MAET,KAAK;AAAA,MACL,KAAK;AACH,eAAO,eAAe,cAAc;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;;;AEhSA,OAAOC,SAAQ;AAMf,eAAsB,KAAK,UAAuB,CAAC,GAAkB;AAEnE,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,IAAIC,SAAQ;AAClB,IAAE,MAAM,oBAAoB;AAC5B,QAAM,aAAa,MAAM,mBAAmB,MAAM;AAClD,MAAI,WAAW,QAAQ;AACrB,UAAM,qBAAqB;AAAA,EAC7B;AACA,IAAE,KAAK,EAAE;AAET,MAAI,WAAW,OAAO;AACpB,IAAAD,KAAI,KAAK,SAAS,aAAa;AAAA,EACjC;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,QAAM,iBAAiB,WAAW,OAAO,KAAK,SAAS,KAAK,IAAI,CAAC;AAEjE,MAAI,QAAQ,WAAW;AAErB,QAAI,eAAe,WAAW,GAAG;AAC/B,MAAAA,KAAI,KAAK,qBAAqB;AAC9B;AAAA,IACF;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,aAAa,iBAAiB,CAAC;AAC3C,YAAQ,IAAI,EAAE;AAEd,eAAW,QAAQ,eAAe,KAAK,GAAG;AACxC,YAAM,QAAQ,SAAU,MAAM,IAAI;AAClC,YAAM,aAAa,MAAM,WAAW,WAChCD,IAAG,IAAI,KAAK,MAAM,MAAM,GAAG,IAC3B;AACJ,cAAQ,IAAI,KAAK,IAAI,MAAM,UAAU,EAAE;AAAA,IACzC;AAAA,EACF,OAAO;AAEL,UAAM,iBAAiB,MAAM,kBAAkB,MAAM;AAErD,QAAI,eAAe,WAAW,GAAG;AAC/B,MAAAC,KAAI,KAAK,2BAA2B;AACpC;AAAA,IACF;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,aAAa,iBAAiB,CAAC;AAC3C,YAAQ,IAAI,EAAE;AAEd,eAAW,QAAQ,eAAe,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;AAC9E,YAAM,YAAY,eAAe,SAAS,KAAK,IAAI;AACnD,YAAM,OAAO,YAAYD,IAAG,MAAM,QAAG,IAAIA,IAAG,IAAI,QAAG;AACnD,YAAM,OAAO,YAAYA,IAAG,IAAI,cAAc,IAAI;AAClD,cAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,MAAM,IAAI,EAAE;AAAA,IAChD;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIA,IAAG,IAAI,WAAW,OAAO,OAAO,IAAI,EAAE,CAAC;AAAA,EACrD;AAEA,UAAQ,IAAI,EAAE;AAChB;;;AC1EA,eAAsB,OAAO,UAAiC;AAE5D,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAG,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,QAAQ,cAAc,UAAU,OAAO,KAAK,SAAS,KAAK,CAAC;AACjE,MAAI,CAAC,OAAO;AACV,IAAAA,KAAI,MAAM,SAAS,QAAQ,0BAA0B;AACrD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,SAAS,MAAM,KAAK;AAClC,MAAI,MAAM,WAAW,YAAY;AAC/B,IAAAA,KAAI,KAAK,SAAS,cAAc,KAAK,CAAC;AACtC;AAAA,EACF;AAEA,QAAM,qBAAqB,OAAO;AAAA,IAChC,QAAQ;AAAA,IACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACrC,CAAC;AAED,EAAAA,KAAI,QAAQ,SAAS,cAAc,KAAK,CAAC;AAC3C;;;AC3CA,SAAS,QAAAC,cAAY;AAerB,eAAsB,OAAO,UAAiC;AAE5D,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,UAAU;AACb,IAAAA,KAAI,MAAM,SAAS,UAAU;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,QAAQ,cAAc,UAAU,OAAO,KAAK,SAAS,KAAK,CAAC;AACjE,MAAI,CAAC,OAAO;AACV,IAAAA,KAAI,MAAM,SAAS,QAAQ,0BAA0B;AACrD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,SAAS,MAAM,KAAK;AAClC,MAAI,MAAM,WAAW,YAAY;AAC/B,IAAAA,KAAI,KAAK,SAAS,cAAc,KAAK,CAAC;AACtC;AAAA,EACF;AAEA,QAAM,YAAY,aAAa;AAC/B,QAAM,WAAW,gBAAgB,KAAK;AACtC,QAAM,YAAYC,OAAK,WAAW,QAAQ;AAC1C,QAAM,aAAaA,OAAK,OAAO,OAAO,MAAM,QAAQ;AAGpD,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,IAAAD,KAAI,MAAM,SAAS,mBAAmB,KAAK,CAAC;AAC5C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,IAAAA,KAAI,MAAM,SAAS,kBAAkB,KAAK,CAAC;AAC3C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,YAAY,MAAM,SAAS,SAAS;AAC1C,QAAM,aAAa,MAAM,SAAS,UAAU;AAE5C,MAAI,cAAc,YAAY;AAE5B,UAAM,qBAAqB,OAAO;AAAA,MAChC,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AACD,IAAAA,KAAI,QAAQ,SAAS,cAAc,KAAK,CAAC;AACzC;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,oBAAoB,KAAK;AAE9C,MAAIE,UAAS,MAAM,GAAG;AACpB,IAAAF,KAAI,KAAK,YAAY;AACrB;AAAA,EACF;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,YAAM,SAAS,YAAY,SAAS;AACpC,YAAM,UAAU,MAAM,SAAS,SAAS;AACxC,YAAM,qBAAqB,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR;AAAA,QACA,WAAW;AAAA,QACX,YAAY;AAAA,MACd,CAAC;AACD,MAAAA,KAAI,QAAQ,SAAS,cAAc,KAAK,CAAC;AACzC;AAAA,IAEF,KAAK;AACH,YAAM,qBAAqB,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd,CAAC;AACD,MAAAA,KAAI,QAAQ,GAAG,KAAK,mCAAmC;AACvD;AAAA,IAEF,KAAK;AACH,MAAAA,KAAI,KAAK,YAAY;AACrB;AAAA,EACJ;AACF;;;AChGA,SAAS,QAAAG,cAAY;AAErB,eAAsB,aAA4B;AAChD,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAC,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,sBAAsB,CAAC;AAChD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,OAAO,OAAO,IAAI,EAAE;AAC7C,UAAQ,IAAI,aAAa,WAAW,OAAO,OAAO,IAAI,CAAC,EAAE;AAEzD,MAAI,OAAO,OAAO,QAAQ;AACxB,YAAQ,IAAI,aAAa,OAAO,OAAO,MAAM,EAAE;AAAA,EACjD,WAAW,UAAU,OAAO,OAAO,IAAI,GAAG;AACxC,UAAM,SAAS,MAAM,aAAa,OAAO,OAAO,IAAI;AACpD,QAAI,QAAQ;AACV,cAAQ,IAAI,aAAa,MAAM,EAAE;AAAA,IACnC;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,iBAAiB,OAAO,SAAS,WAAW,YAAY,UAAU,EAAE;AAChF,UAAQ,IAAI,iBAAiB,OAAO,SAAS,aAAa,EAAE;AAC5D,MAAI,OAAO,SAAS,UAAU;AAC5B,YAAQ,IAAI,iBAAiB,IAAI,KAAK,OAAO,SAAS,QAAQ,EAAE,eAAe,CAAC,EAAE;AAAA,EACpF;AACA,UAAQ,IAAI,EAAE;AAChB;AAEA,eAAsB,UAAU,WAAkC;AAhDlE;AAiDE,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAA,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,SAAS,SAAS,GAAG;AAEvB,UAAM,IAAIC,SAAQ;AAClB,MAAE,MAAM,uBAAuB;AAG/B,UAAM,aAAW,eAAU,MAAM,GAAG,EAAE,IAAI,MAAzB,mBAA4B,QAAQ,QAAQ,QAAO;AACpE,UAAM,YAAY,YAAY,eAAe,QAAQ,EAAE;AAEvD,QAAI;AACF,gBAAUF,OAAK,WAAW,IAAI,CAAC;AAC/B,YAAM,UAAU,WAAW,SAAS;AACpC,QAAE,KAAK,iCAAiC;AAExC,aAAO,SAAS;AAAA,QACd,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,IACF,SAAS,OAAO;AACd,QAAE,KAAK,6BAA6B;AACpC,MAAAC,KAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAChE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AAEL,UAAM,eAAe,YAAY,SAAS;AAE1C,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,MAAAA,KAAI,MAAM,SAAS,eAAe,YAAY,CAAC;AAC/C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,WAAO,SAAS;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAGA,QAAI,UAAU,YAAY,GAAG;AAC3B,YAAM,SAAS,MAAM,aAAa,YAAY;AAC9C,UAAI,QAAQ;AACV,eAAO,OAAO,OAAO;AACrB,eAAO,OAAO,SAAS;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,MAAM;AACvB,EAAAA,KAAI,QAAQ,SAAS,cAAc,OAAO,OAAO,IAAI,CAAC;AACxD;AAEA,eAAsB,aAA4B;AAChD,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAA,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAC,UAAU,OAAO,OAAO,IAAI,GAAG;AAClC,IAAAA,KAAI,MAAM,iCAAiC;AAC3C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,CAAE,MAAM,UAAU,OAAO,OAAO,IAAI,GAAI;AAC1C,IAAAA,KAAI,MAAM,6CAA6C;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,IAAIC,SAAQ;AAClB,IAAE,MAAM,wBAAwB;AAEhC,MAAI;AACF,UAAM,SAAS,OAAO,OAAO,IAAI;AACjC,MAAE,KAAK,8BAA8B;AAGrC,WAAO,SAAS,YAAW,oBAAI,KAAK,GAAE,YAAY;AAClD,UAAM,WAAW,MAAM;AAAA,EACzB,SAAS,OAAO;AACd,MAAE,KAAK,6BAA6B;AACpC,IAAAD,KAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AASA,eAAsB,aAAa,SAA6C;AAC9E,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,QAAQ;AACX,IAAAA,KAAI,MAAM,SAAS,aAAa;AAChC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,QAAQ,aAAa,UAAa,QAAQ,cAAc,QAAW;AACrE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,aAAa,eAAe,CAAC;AACzC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,iBAAiB,OAAO,SAAS,WAAW,YAAY,UAAU,EAAE;AAChF,YAAQ,IAAI,iBAAiB,OAAO,SAAS,aAAa,EAAE;AAC5D,QAAI,OAAO,SAAS,UAAU;AAC5B,cAAQ,IAAI,iBAAiB,IAAI,KAAK,OAAO,SAAS,QAAQ,EAAE,eAAe,CAAC,EAAE;AAAA,IACpF;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,uDAAuD;AACnE,YAAQ,IAAI,EAAE;AACd;AAAA,EACF;AAGA,MAAI,QAAQ,aAAa,QAAW;AAClC,WAAO,SAAS,WAAW,QAAQ;AAAA,EACrC;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,WAAO,SAAS,gBAAgB,QAAQ;AAAA,EAC1C;AAEA,QAAM,WAAW,MAAM;AAEvB,EAAAA,KAAI,QAAQ,mBAAmB;AAC/B,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,iBAAiB,OAAO,SAAS,WAAW,YAAY,UAAU,EAAE;AAChF,UAAQ,IAAI,iBAAiB,OAAO,SAAS,aAAa,EAAE;AAC5D,UAAQ,IAAI,EAAE;AAChB;;;AC3LA,SAAS,QAAAE,cAAY;AAcrB,OAAOC,SAAQ;AAQf,eAAsB,SAAwB;AAC5C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,wBAAwB,CAAC;AAClD,UAAQ,IAAI,EAAE;AAEd,QAAM,UAA8B,CAAC;AAGrC,QAAM,aAAa,cAAc;AACjC,MAAI,WAAW,UAAU,GAAG;AAC1B,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,YAAY,WAAW,UAAU,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,kBAAkBA,IAAG,KAAK,SAAS,CAAC;AAAA,IAC/C,CAAC;AAAA,EACH;AAGA,QAAM,SAAS,MAAM,WAAW;AAEhC,MAAI,QAAQ;AAEV,QAAI,WAAW,OAAO,OAAO,IAAI,GAAG;AAClC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS,WAAW,OAAO,OAAO,IAAI;AAAA,MACxC,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS,wBAAwB,WAAW,OAAO,OAAO,IAAI,CAAC;AAAA,MACjE,CAAC;AAAA,IACH;AAGA,QAAI,WAAW,OAAO,OAAO,IAAI,GAAG;AAClC,YAAM,iBAAiB,MAAM,kBAAkB,MAAM;AACrD,UAAI,eAAe,SAAS,GAAG;AAC7B,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS,GAAG,eAAe,MAAM;AAAA,QACnC,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,OAAO,OAAO,SAAS,SAAS,WAAW,OAAO,OAAO,IAAI,GAAG;AAClE,UAAI,UAAU,OAAO,OAAO,IAAI,GAAG;AACjC,YAAI,MAAM,UAAU,OAAO,OAAO,IAAI,GAAG;AACvC,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC;AAAA,QACH,OAAO;AACL,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,aAAa;AAC/B,QAAM,gBAAgB,iBAAiB;AAEvC,MAAI,WAAW,SAAS,GAAG;AACzB,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH,OAAO;AACL,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAGA,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,UAAU;AACZ,UAAM,YAAY,OAAO,KAAK,SAAS,KAAK,EAAE;AAC9C,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,GAAG,SAAS;AAAA,IACvB,CAAC;AAGD,QAAI,UAAU,YAAY,GAAG;AAC3B,UAAI,eAAe;AACnB,iBAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG;AAC9D,cAAM,YAAYC,OAAK,WAAW,MAAM,IAAI;AAC5C,YAAI,CAAC,WAAW,SAAS,GAAG;AAC1B;AAAA,QACF;AAAA,MACF;AAEA,UAAI,eAAe,GAAG;AACpB,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS,GAAG,YAAY;AAAA,QAC1B,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,WAAW,WAAW,SAAS,GAAG;AAChC,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS,oBAAoBD,IAAG,KAAK,QAAQ,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAGA,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,aAAW,UAAU,SAAS;AAC5B,QAAI;AACJ,QAAI;AAEJ,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK;AACH,eAAO;AACP,gBAAQA,IAAG;AACX;AACA;AAAA,MACF,KAAK;AACH,eAAO;AACP,gBAAQA,IAAG;AACX;AACA;AAAA,MACF,KAAK;AACH,eAAO;AACP,gBAAQA,IAAG;AACX;AACA;AAAA,IACJ;AAEA,YAAQ,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,OAAO,OAAO,EAAE;AAAA,EAClE;AAEA,UAAQ,IAAI,EAAE;AAEd,MAAI,YAAY,GAAG;AACjB,IAAAE,KAAI,MAAM,SAAS,kBAAkB,SAAS,CAAC;AAAA,EACjD,WAAW,YAAY,GAAG;AACxB,IAAAA,KAAI,KAAK,GAAG,SAAS,oBAAoB;AAAA,EAC3C,OAAO;AACL,IAAAA,KAAI,QAAQ,SAAS,aAAa;AAAA,EACpC;AACF;;;AxB1LA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,cAAcA,SAAQ,iBAAiB;AAG7C,eAAe,EAAE,KAAK,YAAY,CAAC,EAAE,OAAO,EAAE,UAAU,KAAK,CAAC;AAE9D,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,YAAY,EACjB,YAAY,mDAAmD,EAC/D,QAAQ,YAAY,OAAO;AAE9B,QACG,QAAQ,MAAM,EACd,YAAY,0BAA0B,EACtC,OAAO,eAAe,kCAAkC,EACxD,OAAO,OAAO,YAAY;AACzB,QAAM,KAAK,EAAE,OAAO,QAAQ,MAAM,CAAC;AACrC,CAAC;AAEH,QACG,QAAQ,gBAAgB,EACxB,YAAY,8BAA8B,EAC1C,OAAO,aAAa,yBAAyB,EAC7C,OAAO,OAAO,OAAO,YAAY;AAChC,QAAM,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC;AACvC,CAAC;AAEH,QACG,QAAQ,mBAAmB,EAC3B,YAAY,2BAA2B,EACvC,OAAO,mBAAmB,gDAAgD,EAC1E,OAAO,OAAO,OAAO,YAAY;AAChC,QAAM,OAAO,OAAO,EAAE,UAAU,QAAQ,SAAS,CAAC;AACpD,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,qCAAqC,EACjD,OAAO,YAAY;AAClB,QAAM,OAAO;AACf,CAAC;AAEH,QACG,QAAQ,iBAAiB,EACzB,YAAY,0BAA0B,EACtC,OAAO,eAAe,4CAA4C,EAClE,OAAO,sBAAsB,wBAAwB,EACrD,OAAO,OAAO,OAAO,YAAY;AAChC,QAAM,KAAK,OAAO;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,iBAAiB,QAAQ;AAAA,EAC3B,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,aAAa,EACrB,YAAY,2CAA2C,EACvD,OAAO,aAAa,kCAAkC,EACtD,OAAO,OAAO,MAAM,YAAY;AAC/B,QAAM,QAAQ,OAAO,CAAC,IAAI,IAAI,CAAC;AAC/B,QAAM,KAAK,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC;AACxC,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,sBAAsB,EAClC,OAAO,mBAAmB,2BAA2B,EACrD,OAAO,OAAO,YAAY;AACzB,QAAM,KAAK,EAAE,WAAW,QAAQ,UAAU,CAAC;AAC7C,CAAC;AAEH,QACG,QAAQ,eAAe,EACvB,YAAY,qCAAqC,EACjD,OAAO,OAAO,SAAS;AACtB,QAAM,OAAO,IAAI;AACnB,CAAC;AAEH,QACG,QAAQ,eAAe,EACvB,YAAY,iCAAiC,EAC7C,OAAO,OAAO,SAAS;AACtB,QAAM,OAAO,IAAI;AACnB,CAAC;AAGH,IAAM,YAAY,QACf,QAAQ,QAAQ,EAChB,YAAY,6BAA6B;AAE5C,UACG,QAAQ,MAAM,EACd,YAAY,mCAAmC,EAC/C,OAAO,YAAY;AAClB,QAAM,WAAW;AACnB,CAAC;AAEH,UACG,QAAQ,mBAAmB,EAC3B,YAAY,wBAAwB,EACpC,OAAO,OAAO,cAAc;AAC3B,QAAM,UAAU,SAAS;AAC3B,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,YAAY;AAClB,QAAM,WAAW;AACnB,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,8BAA8B,EAC1C,OAAO,yBAAyB,sCAAsC,EACtE,OAAO,sBAAsB,4CAA4C,EACzE,OAAO,OAAO,YAAY;AACzB,MAAI;AACJ,MAAI,QAAQ,aAAa,QAAW;AAClC,UAAM,MAAM,QAAQ,SAAS,YAAY;AACzC,QAAI,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,KAAK;AACjD,iBAAW;AAAA,IACb,WAAW,QAAQ,SAAS,QAAQ,WAAW,QAAQ,KAAK;AAC1D,iBAAW;AAAA,IACb,OAAO;AACL,cAAQ,MAAM,0DAA0D;AACxE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,QAAQ,cAAc,QAAW;AACnC,UAAM,MAAM,QAAQ,UAAU,YAAY;AAC1C,QAAI,QAAQ,YAAY,QAAQ,WAAW,QAAQ,UAAU;AAC3D,kBAAY;AAAA,IACd,OAAO;AACL,cAAQ,MAAM,2DAA2D;AACzE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,aAAa,EAAE,UAAU,UAAU,CAAC;AAC5C,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,OAAO,YAAY;AAClB,QAAM,OAAO;AACf,CAAC;AAEH,QAAQ,MAAM;","names":["join","parse","stringify","parse","stringify","join","readFile","join","join","status","text","pc","pc","pc","isCancel","spinner","intro","pc","outro","log","intro","log","isCancel","spinner","join","outro","join","log","spinner","isCancel","join","join","log","join","join","log","spinner","join","status","join","join","log","join","diff","sourceSet","log","spinner","join","isCancel","pc","log","spinner","log","join","log","join","isCancel","join","log","spinner","join","pc","join","log","require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/lib/config.ts","../src/lib/paths.ts","../src/lib/files.ts","../src/types/config.ts","../src/types/manifest.ts","../src/lib/manifest.ts","../src/lib/source.ts","../src/lib/hash.ts","../src/lib/git.ts","../src/lib/platform.ts","../src/ui/format.ts","../src/ui/messages.ts","../src/ui/prompts.ts","../src/commands/add.ts","../src/commands/remove.ts","../src/commands/status.ts","../src/commands/pull.ts","../src/commands/diff.ts","../src/commands/list.ts","../src/commands/detach.ts","../src/commands/attach.ts","../src/commands/source.ts","../src/commands/doctor.ts"],"sourcesContent":["import { createRequire } from 'module'\nimport { Command } from 'commander'\nimport updateNotifier from 'update-notifier'\nimport {\n init,\n add,\n remove,\n status,\n pull,\n diff,\n list,\n detach,\n attach,\n sourceShow,\n sourceSet,\n sourcePull,\n sourceConfig,\n doctor\n} from './commands/index.js'\nimport type { PullFrequency } from './types/index.js'\n\nconst require = createRequire(import.meta.url)\nconst packageJson = require('../package.json')\n\n// Check for updates (runs in background, shows message at exit if update available)\nupdateNotifier({ pkg: packageJson }).notify({ isGlobal: true })\n\nconst program = new Command()\n\nprogram\n .name('rulekeeper')\n .description('Sync and manage Claude Code rules across projects')\n .version(packageJson.version)\n\nprogram\n .command('init')\n .description('Interactive global setup')\n .option('-f, --force', 'Overwrite existing configuration')\n .action(async (options) => {\n await init({ force: options.force })\n })\n\nprogram\n .command('add [rules...]')\n .description('Add rules to current project')\n .option('-a, --all', 'Add all available rules')\n .action(async (rules, options) => {\n await add(rules, { all: options.all })\n })\n\nprogram\n .command('remove <rules...>')\n .description('Remove rules from project')\n .option('-k, --keep-file', 'Keep the local file, only remove from manifest')\n .action(async (rules, options) => {\n await remove(rules, { keepFile: options.keepFile })\n })\n\nprogram\n .command('status')\n .description('Show rule states in current project')\n .action(async () => {\n await status()\n })\n\nprogram\n .command('pull [rules...]')\n .description('Update rules from source')\n .option('-f, --force', 'Overwrite diverged rules without prompting')\n .option('--include-detached', 'Include detached rules')\n .action(async (rules, options) => {\n await pull(rules, {\n force: options.force,\n includeDetached: options.includeDetached\n })\n })\n\nprogram\n .command('diff [rule]')\n .description('Show differences between local and source')\n .option('-a, --all', 'Show diff for all diverged rules')\n .action(async (rule, options) => {\n const rules = rule ? [rule] : []\n await diff(rules, { all: options.all })\n })\n\nprogram\n .command('list')\n .description('List available rules')\n .option('-i, --installed', 'Show only installed rules')\n .action(async (options) => {\n await list({ installed: options.installed })\n })\n\nprogram\n .command('detach <rule>')\n .description('Mark rule as intentionally diverged')\n .action(async (rule) => {\n await detach(rule)\n })\n\nprogram\n .command('attach <rule>')\n .description('Resume tracking a detached rule')\n .action(async (rule) => {\n await attach(rule)\n })\n\n// Source subcommands\nconst sourceCmd = program\n .command('source')\n .description('Manage source configuration')\n\nsourceCmd\n .command('show')\n .description('Show current source configuration')\n .action(async () => {\n await sourceShow()\n })\n\nsourceCmd\n .command('set <path-or-url>')\n .description('Change source location')\n .action(async (pathOrUrl) => {\n await sourceSet(pathOrUrl)\n })\n\nsourceCmd\n .command('pull')\n .description('Manually pull from git remote')\n .action(async () => {\n await sourcePull()\n })\n\nsourceCmd\n .command('config')\n .description('View or update pull settings')\n .option('--auto-pull <boolean>', 'Enable or disable auto-pull (on/off)')\n .option('--frequency <freq>', 'Set pull frequency (always, daily, weekly)')\n .action(async (options) => {\n let autoPull: boolean | undefined\n if (options.autoPull !== undefined) {\n const val = options.autoPull.toLowerCase()\n if (val === 'on' || val === 'true' || val === '1') {\n autoPull = true\n } else if (val === 'off' || val === 'false' || val === '0') {\n autoPull = false\n } else {\n console.error('Invalid value for --auto-pull. Use: on, off, true, false')\n process.exit(1)\n }\n }\n\n let frequency: PullFrequency | undefined\n if (options.frequency !== undefined) {\n const val = options.frequency.toLowerCase()\n if (val === 'always' || val === 'daily' || val === 'weekly') {\n frequency = val as PullFrequency\n } else {\n console.error('Invalid value for --frequency. Use: always, daily, weekly')\n process.exit(1)\n }\n }\n\n await sourceConfig({ autoPull, frequency })\n })\n\nprogram\n .command('doctor')\n .description('Diagnose setup issues')\n .action(async () => {\n await doctor()\n })\n\nprogram.parse()\n","import { join } from 'node:path'\nimport pc from 'picocolors'\nimport {\n loadConfig,\n saveConfig,\n createConfig,\n configExists,\n expandTilde,\n fileExists,\n ensureDir,\n cloneRepo,\n isGitRepo,\n getRemoteUrl\n} from '../lib/index.js'\nimport {\n intro,\n outro,\n log,\n spinner,\n isCancel,\n selectSourceType,\n inputSourcePath,\n inputGitUrl,\n inputClonePath,\n selectPullFrequency,\n selectWindowsShell\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { isWindows, detectWindowsShell } from '../lib/platform.js'\nimport type { SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\ninterface InitOptions {\n force?: boolean\n}\n\nexport async function init(options: InitOptions = {}): Promise<void> {\n intro(messages.initWelcome)\n\n // Check if already configured\n if (!options.force && await configExists()) {\n log.warn(messages.initAlreadyExists)\n return\n }\n\n // Select source type\n const sourceType = await selectSourceType()\n if (isCancel(sourceType)) {\n log.info('Setup cancelled.')\n return\n }\n\n let sourcePath: string\n let remote: string | undefined\n let detectedSourceType: SourceType = sourceType as SourceType\n\n if (sourceType === 'git') {\n // Git clone flow with retry\n while (true) {\n const gitUrl = await inputGitUrl()\n if (isCancel(gitUrl)) {\n log.info('Setup cancelled.')\n return\n }\n\n const clonePath = await inputClonePath()\n if (isCancel(clonePath)) {\n log.info('Setup cancelled.')\n return\n }\n\n const expandedClonePath = expandTilde(clonePath as string)\n\n const s = spinner()\n s.start('Cloning repository...')\n\n try {\n ensureDir(join(expandedClonePath, '..'))\n await cloneRepo(gitUrl as string, expandedClonePath)\n s.stop('Repository cloned successfully.')\n sourcePath = expandedClonePath\n remote = gitUrl as string\n break\n } catch (error) {\n s.stop('Failed to clone repository.')\n log.error(error instanceof Error ? error.message : String(error))\n log.info('Please try again.')\n }\n }\n } else {\n // Local path flow with retry\n while (true) {\n const localPath = await inputSourcePath()\n if (isCancel(localPath)) {\n log.info('Setup cancelled.')\n return\n }\n\n const expandedPath = expandTilde(localPath as string)\n\n if (!fileExists(expandedPath)) {\n log.error(messages.sourceNotFound(expandedPath))\n log.info('Please try again.')\n continue\n }\n\n sourcePath = expandedPath\n\n // Auto-detect if it's a git repo with a remote\n if (isGitRepo(expandedPath)) {\n const detectedRemote = await getRemoteUrl(expandedPath)\n if (detectedRemote) {\n detectedSourceType = 'git'\n remote = detectedRemote\n log.info(`Detected git repository with remote: ${detectedRemote}`)\n }\n }\n break\n }\n }\n\n // Select pull frequency\n const pullFrequency = await selectPullFrequency()\n if (isCancel(pullFrequency)) {\n log.info('Setup cancelled.')\n return\n }\n\n // Windows shell selection\n let shell: WindowsShell | undefined\n if (isWindows()) {\n const detectedShell = detectWindowsShell()\n if (detectedShell) {\n log.info(`Detected shell: ${detectedShell}`)\n shell = detectedShell\n } else {\n const selectedShell = await selectWindowsShell()\n if (isCancel(selectedShell)) {\n log.info('Setup cancelled.')\n return\n }\n shell = selectedShell as WindowsShell\n }\n }\n\n // Create and save config\n const config = createConfig({\n sourceType: detectedSourceType,\n sourcePath,\n remote,\n autoPull: true,\n pullFrequency: pullFrequency as PullFrequency,\n shell\n })\n\n await saveConfig(config)\n\n outro(messages.initSuccess)\n\n // Show next steps\n log.info('')\n log.info('Next steps:')\n log.info(` • Navigate to a project: ${pc.dim('cd my-project')}`)\n log.info(` • Add all rules: ${pc.cyan('rk add -a')}`)\n log.info(` • Or add specific rule: ${pc.cyan('rk add <rule-name>')}`)\n log.info(` • List available rules: ${pc.cyan('rk list')}`)\n}\n","import { parse, stringify } from 'yaml'\nimport { getConfigPath, getConfigDir } from './paths.js'\nimport { fileExists, readTextFile, writeTextFile, ensureDir } from './files.js'\nimport { DEFAULT_CONFIG } from '../types/index.js'\nimport type { GlobalConfig, SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\nexport async function loadConfig(): Promise<GlobalConfig | null> {\n const configPath = getConfigPath()\n\n if (!fileExists(configPath)) {\n return null\n }\n\n const content = await readTextFile(configPath)\n const config = parse(content) as GlobalConfig\n\n return config\n}\n\nexport async function saveConfig(config: GlobalConfig): Promise<void> {\n const configPath = getConfigPath()\n ensureDir(getConfigDir())\n\n const content = stringify(config, { indent: 2 })\n await writeTextFile(configPath, content)\n}\n\nexport async function configExists(): Promise<boolean> {\n return fileExists(getConfigPath())\n}\n\nexport function createConfig(options: {\n sourceType: SourceType\n sourcePath: string\n remote?: string\n autoPull?: boolean\n pullFrequency?: PullFrequency\n shell?: WindowsShell\n}): GlobalConfig {\n const config: GlobalConfig = {\n ...DEFAULT_CONFIG,\n source: {\n type: options.sourceType,\n path: options.sourcePath,\n remote: options.remote\n },\n settings: {\n autoPull: options.autoPull ?? true,\n pullFrequency: options.pullFrequency ?? 'daily'\n }\n }\n\n if (options.shell) {\n config.platform = { shell: options.shell }\n }\n\n return config\n}\n\nexport async function updateConfigLastPull(): Promise<void> {\n const config = await loadConfig()\n if (config) {\n config.settings.lastPull = new Date().toISOString()\n await saveConfig(config)\n }\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport envPaths from 'env-paths'\n\nconst paths = envPaths('rulekeeper', { suffix: '' })\n\nexport function getConfigDir(): string {\n return paths.config\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), 'config.yaml')\n}\n\nexport function getClaudeDir(projectPath: string = process.cwd()): string {\n return join(projectPath, '.claude', 'rules')\n}\n\nexport function getRulekeeperDir(projectPath: string = process.cwd()): string {\n return join(projectPath, '.rulekeeper')\n}\n\nexport function getManifestPath(projectPath: string = process.cwd()): string {\n return join(getRulekeeperDir(projectPath), 'manifest.yaml')\n}\n\nexport function getHomeDir(): string {\n return homedir()\n}\n\nexport function expandTilde(path: string): string {\n if (path.startsWith('~')) {\n return join(getHomeDir(), path.slice(1))\n }\n return path\n}\n","import { existsSync, mkdirSync } from 'node:fs'\nimport { readFile, writeFile, copyFile as fsCopyFile, readdir, unlink, rm } from 'node:fs/promises'\nimport { dirname, join, basename } from 'node:path'\n\n// Files to ignore when listing/processing rules (case-insensitive)\nexport const IGNORED_FILES = ['readme.md']\n\nexport function isIgnoredRule(ruleName: string): boolean {\n const filename = getRuleFilename(ruleName)\n return IGNORED_FILES.includes(filename.toLowerCase())\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true })\n }\n}\n\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath)\n}\n\nexport async function readTextFile(filePath: string): Promise<string> {\n return await readFile(filePath, 'utf-8')\n}\n\nexport async function writeTextFile(filePath: string, content: string): Promise<void> {\n ensureDir(dirname(filePath))\n await writeFile(filePath, content, 'utf-8')\n}\n\nexport async function copyFile(source: string, dest: string): Promise<void> {\n ensureDir(dirname(dest))\n await fsCopyFile(source, dest)\n}\n\nexport async function deleteFile(filePath: string): Promise<void> {\n if (existsSync(filePath)) {\n await unlink(filePath)\n }\n}\n\nexport async function deleteDir(dirPath: string): Promise<void> {\n if (existsSync(dirPath)) {\n await rm(dirPath, { recursive: true, force: true })\n }\n}\n\nexport async function listFiles(dirPath: string, extension?: string): Promise<string[]> {\n if (!existsSync(dirPath)) {\n return []\n }\n\n const entries = await readdir(dirPath, { withFileTypes: true })\n let files = entries\n .filter(entry => entry.isFile())\n .map(entry => entry.name)\n\n if (extension) {\n files = files.filter(file => file.endsWith(extension))\n }\n\n return files\n}\n\nexport function getRuleName(filename: string): string {\n // Remove .md extension to get rule name\n return basename(filename, '.md')\n}\n\nexport function getRuleFilename(ruleName: string): string {\n // Remove .md extension if already present, then add it back\n // This handles both \"laravel\" and \"laravel.md\" inputs\n const baseName = ruleName.toLowerCase().endsWith('.md')\n ? ruleName.slice(0, -3)\n : ruleName\n return `${baseName}.md`\n}\n\nexport function normalizeRuleName(ruleName: string): string {\n // Normalize rule name: remove .md extension and lowercase\n const name = ruleName.toLowerCase().endsWith('.md')\n ? ruleName.slice(0, -3)\n : ruleName\n return name.toLowerCase()\n}\n\nexport function findRuleMatch(\n input: string,\n availableRules: string[]\n): string | null {\n // Find a rule case-insensitively\n const normalizedInput = normalizeRuleName(input)\n\n // First try exact match (case-insensitive)\n const match = availableRules.find(\n rule => normalizeRuleName(rule) === normalizedInput\n )\n\n return match ?? null\n}\n","export type SourceType = 'local' | 'git'\nexport type PullFrequency = 'always' | 'daily' | 'weekly' | 'never'\nexport type WindowsShell = 'standard' | 'gitbash' | 'wsl'\n\nexport interface SourceConfig {\n type: SourceType\n path: string\n remote?: string\n}\n\nexport interface SettingsConfig {\n autoPull: boolean\n pullFrequency: PullFrequency\n lastPull?: string\n}\n\nexport interface PlatformConfig {\n shell?: WindowsShell\n}\n\nexport interface GlobalConfig {\n version: number\n source: SourceConfig\n settings: SettingsConfig\n platform?: PlatformConfig\n}\n\nexport const DEFAULT_CONFIG: GlobalConfig = {\n version: 1,\n source: {\n type: 'local',\n path: ''\n },\n settings: {\n autoPull: true,\n pullFrequency: 'daily'\n }\n}\n","export type RuleStatus = 'synced' | 'outdated' | 'diverged' | 'detached'\n\nexport interface RuleEntry {\n file: string\n sourceHash: string\n localHash: string\n status: RuleStatus\n installedAt: string\n updatedAt: string\n detachedAt?: string\n}\n\nexport interface ProjectManifest {\n version: number\n rules: Record<string, RuleEntry>\n}\n\nexport const DEFAULT_MANIFEST: ProjectManifest = {\n version: 1,\n rules: {}\n}\n\nexport interface StatusCheckResult {\n status: RuleStatus\n localChanged: boolean\n sourceChanged: boolean\n localExists: boolean\n sourceExists: boolean\n currentLocalHash?: string\n currentSourceHash?: string\n}\n","import { parse, stringify } from 'yaml'\nimport { getManifestPath, getRulekeeperDir } from './paths.js'\nimport { fileExists, readTextFile, writeTextFile, ensureDir } from './files.js'\nimport { DEFAULT_MANIFEST } from '../types/index.js'\nimport type { ProjectManifest, RuleEntry, RuleStatus } from '../types/index.js'\n\nexport async function loadManifest(projectPath: string = process.cwd()): Promise<ProjectManifest | null> {\n const manifestPath = getManifestPath(projectPath)\n\n if (!fileExists(manifestPath)) {\n return null\n }\n\n const content = await readTextFile(manifestPath)\n const manifest = parse(content) as ProjectManifest\n\n return manifest\n}\n\nexport async function saveManifest(manifest: ProjectManifest, projectPath: string = process.cwd()): Promise<void> {\n const manifestPath = getManifestPath(projectPath)\n ensureDir(getRulekeeperDir(projectPath))\n\n const content = stringify(manifest, { indent: 2 })\n await writeTextFile(manifestPath, content)\n}\n\nexport async function manifestExists(projectPath: string = process.cwd()): Promise<boolean> {\n return fileExists(getManifestPath(projectPath))\n}\n\nexport async function getOrCreateManifest(projectPath: string = process.cwd()): Promise<ProjectManifest> {\n const manifest = await loadManifest(projectPath)\n return manifest ?? { ...DEFAULT_MANIFEST }\n}\n\nexport function createRuleEntry(options: {\n file: string\n sourceHash: string\n localHash: string\n status?: RuleStatus\n}): RuleEntry {\n const now = new Date().toISOString()\n return {\n file: options.file,\n sourceHash: options.sourceHash,\n localHash: options.localHash,\n status: options.status ?? 'synced',\n installedAt: now,\n updatedAt: now\n }\n}\n\nexport function updateRuleEntry(entry: RuleEntry, updates: Partial<RuleEntry>): RuleEntry {\n return {\n ...entry,\n ...updates,\n updatedAt: new Date().toISOString()\n }\n}\n\nexport async function addRuleToManifest(\n ruleName: string,\n entry: RuleEntry,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await getOrCreateManifest(projectPath)\n manifest.rules[ruleName] = entry\n await saveManifest(manifest, projectPath)\n}\n\nexport async function removeRuleFromManifest(\n ruleName: string,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await loadManifest(projectPath)\n if (manifest && manifest.rules[ruleName]) {\n delete manifest.rules[ruleName]\n await saveManifest(manifest, projectPath)\n }\n}\n\nexport async function updateRuleInManifest(\n ruleName: string,\n updates: Partial<RuleEntry>,\n projectPath: string = process.cwd()\n): Promise<void> {\n const manifest = await loadManifest(projectPath)\n if (manifest && manifest.rules[ruleName]) {\n manifest.rules[ruleName] = updateRuleEntry(manifest.rules[ruleName], updates)\n await saveManifest(manifest, projectPath)\n }\n}\n","import { join } from 'node:path'\nimport { fileExists, listFiles, getRuleFilename, getRuleName, IGNORED_FILES } from './files.js'\nimport { hashFile } from './hash.js'\nimport type { GlobalConfig } from '../types/index.js'\n\nexport interface AvailableRule {\n name: string\n file: string\n path: string\n}\n\nexport async function getAvailableRules(config: GlobalConfig): Promise<AvailableRule[]> {\n const sourcePath = config.source.path\n\n if (!fileExists(sourcePath)) {\n return []\n }\n\n const files = await listFiles(sourcePath, '.md')\n const filteredFiles = files.filter(file => !IGNORED_FILES.includes(file.toLowerCase()))\n\n return filteredFiles.map(file => ({\n name: getRuleName(file),\n file,\n path: join(sourcePath, file)\n }))\n}\n\nexport async function getRuleSourcePath(ruleName: string, config: GlobalConfig): Promise<string | null> {\n const filename = getRuleFilename(ruleName)\n const rulePath = join(config.source.path, filename)\n\n if (!fileExists(rulePath)) {\n return null\n }\n\n return rulePath\n}\n\nexport async function getRuleSourceHash(ruleName: string, config: GlobalConfig): Promise<string | null> {\n const rulePath = await getRuleSourcePath(ruleName, config)\n\n if (!rulePath) {\n return null\n }\n\n return await hashFile(rulePath)\n}\n\nexport function validateSourcePath(path: string): { valid: boolean; error?: string } {\n if (!path) {\n return { valid: false, error: 'Source path is required' }\n }\n\n if (!fileExists(path)) {\n return { valid: false, error: `Source path does not exist: ${path}` }\n }\n\n return { valid: true }\n}\n\nexport function isGitUrl(url: string): boolean {\n return (\n url.startsWith('git@') ||\n url.startsWith('https://github.com') ||\n url.startsWith('https://gitlab.com') ||\n url.startsWith('https://bitbucket.org') ||\n url.endsWith('.git')\n )\n}\n","import { createHash } from 'node:crypto'\nimport { readFile } from 'node:fs/promises'\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath)\n const hash = createHash('sha256').update(content).digest('hex')\n return `sha256:${hash}`\n}\n\nexport async function hashContent(content: string | Buffer): Promise<string> {\n const hash = createHash('sha256').update(content).digest('hex')\n return `sha256:${hash}`\n}\n\nexport function compareHashes(hash1: string, hash2: string): boolean {\n return hash1 === hash2\n}\n","import simpleGit, { SimpleGit } from 'simple-git'\nimport { fileExists } from './files.js'\nimport { join } from 'node:path'\nimport type { GlobalConfig } from '../types/index.js'\n\nexport function isGitRepo(path: string): boolean {\n return fileExists(join(path, '.git'))\n}\n\nexport async function cloneRepo(url: string, targetPath: string): Promise<void> {\n const git = simpleGit()\n await git.clone(url, targetPath)\n}\n\nexport async function pullRepo(path: string): Promise<void> {\n const git = simpleGit(path)\n await git.pull()\n}\n\nexport async function hasRemote(path: string): Promise<boolean> {\n if (!isGitRepo(path)) return false\n\n const git = simpleGit(path)\n try {\n const remotes = await git.getRemotes()\n return remotes.length > 0\n } catch {\n return false\n }\n}\n\nexport async function getRemoteUrl(path: string): Promise<string | null> {\n if (!isGitRepo(path)) return null\n\n const git = simpleGit(path)\n try {\n const remotes = await git.getRemotes(true)\n const origin = remotes.find(r => r.name === 'origin')\n return origin?.refs?.fetch ?? null\n } catch {\n return null\n }\n}\n\nexport function shouldPullFromRemote(config: GlobalConfig): boolean {\n if (!config.settings.autoPull) return false\n if (config.settings.pullFrequency === 'never') return false\n if (!config.settings.lastPull) return true\n\n const lastPull = new Date(config.settings.lastPull)\n const now = new Date()\n const hoursSinceLastPull = (now.getTime() - lastPull.getTime()) / (1000 * 60 * 60)\n\n switch (config.settings.pullFrequency) {\n case 'always':\n return true\n case 'daily':\n return hoursSinceLastPull >= 24\n case 'weekly':\n return hoursSinceLastPull >= 168\n default:\n return false\n }\n}\n\nexport async function pullSourceIfNeeded(config: GlobalConfig): Promise<{ pulled: boolean; error?: string }> {\n const sourcePath = config.source.path\n\n if (!isGitRepo(sourcePath)) {\n return { pulled: false }\n }\n\n if (!shouldPullFromRemote(config)) {\n return { pulled: false }\n }\n\n if (!(await hasRemote(sourcePath))) {\n return { pulled: false }\n }\n\n try {\n await pullRepo(sourcePath)\n return { pulled: true }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { pulled: false, error: message }\n }\n}\n","import type { WindowsShell } from '../types/index.js'\n\nexport function isWindows(): boolean {\n return process.platform === 'win32'\n}\n\nexport function isMac(): boolean {\n return process.platform === 'darwin'\n}\n\nexport function isLinux(): boolean {\n return process.platform === 'linux'\n}\n\nexport function isWSL(): boolean {\n // WSL runs as Linux, not Windows\n if (process.platform !== 'linux') return false\n\n // Check for WSL-specific indicators\n return !!(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP)\n}\n\nexport function detectWindowsShell(): WindowsShell | null {\n // If we're in WSL, platform is linux but we're in a Windows context\n if (isWSL()) {\n return 'wsl'\n }\n\n if (!isWindows()) return null\n\n // Git Bash sets MSYSTEM (MINGW64, MINGW32, MSYS, etc.)\n // Check this FIRST as WSLENV can be set even outside WSL\n if (process.env.MSYSTEM) {\n return 'gitbash'\n }\n\n return 'standard'\n}\n\nexport function getPlatformName(): string {\n if (isWSL()) return 'WSL'\n if (isWindows()) return 'Windows'\n if (isMac()) return 'macOS'\n if (isLinux()) return 'Linux'\n return process.platform\n}\n","import pc from 'picocolors'\nimport type { RuleStatus } from '../types/index.js'\n\nexport function formatRuleStatus(status: RuleStatus): string {\n switch (status) {\n case 'synced':\n return pc.green('✓')\n case 'outdated':\n return pc.yellow('↓')\n case 'diverged':\n return pc.red('⚠')\n case 'detached':\n return pc.dim('○')\n default:\n return pc.dim('?')\n }\n}\n\nexport function formatRuleStatusText(status: RuleStatus): string {\n switch (status) {\n case 'synced':\n return pc.green('synced')\n case 'outdated':\n return pc.yellow('outdated')\n case 'diverged':\n return pc.red('diverged')\n case 'detached':\n return pc.dim('detached')\n default:\n return pc.dim('unknown')\n }\n}\n\nexport function formatRuleLine(name: string, status: RuleStatus, details?: string): string {\n const icon = formatRuleStatus(status)\n const statusText = formatRuleStatusText(status)\n const detailsPart = details ? pc.dim(` (${details})`) : ''\n\n return ` ${icon} ${name.padEnd(20)} ${statusText}${detailsPart}`\n}\n\nexport function formatError(message: string): string {\n return pc.red(`✗ ${message}`)\n}\n\nexport function formatSuccess(message: string): string {\n return pc.green(`✓ ${message}`)\n}\n\nexport function formatWarning(message: string): string {\n return pc.yellow(`⚠ ${message}`)\n}\n\nexport function formatInfo(message: string): string {\n return pc.blue(`ℹ ${message}`)\n}\n\nexport function formatDim(message: string): string {\n return pc.dim(message)\n}\n\nexport function formatPath(path: string): string {\n return pc.cyan(path)\n}\n\nexport function formatCommand(command: string): string {\n return pc.cyan(`\\`${command}\\``)\n}\n\nexport function formatHeader(text: string): string {\n return pc.bold(text)\n}\n\nexport function formatDiffAdd(line: string): string {\n return pc.green(`+ ${line}`)\n}\n\nexport function formatDiffRemove(line: string): string {\n return pc.red(`- ${line}`)\n}\n\nexport function formatDiffContext(line: string): string {\n return pc.dim(` ${line}`)\n}\n\nexport function formatDiffHeader(line: string): string {\n return pc.cyan(line)\n}\n","import pc from 'picocolors'\nimport { formatCommand, formatPath } from './format.js'\n\nexport const messages = {\n // General\n notConfigured: `RuleKeeper is not configured. Run ${formatCommand('rk init')} first.`,\n noManifest: `No RuleKeeper manifest found. Run ${formatCommand('rk add')} first.`,\n noClaudeDir: `No .claude/rules/ directory found. Are you in a project root?`,\n\n // Init\n initWelcome: 'Welcome to RuleKeeper!',\n initSuccess: 'RuleKeeper is now configured.',\n initAlreadyExists: 'RuleKeeper is already configured. Use --force to reconfigure.',\n\n // Source\n sourceNotFound: (path: string) => `Source path does not exist: ${formatPath(path)}`,\n sourceInvalid: 'Invalid source path or URL.',\n sourceUpdated: (path: string) => `Source updated to: ${formatPath(path)}`,\n\n // Add\n addSuccess: (count: number) => `Added ${count} rule${count !== 1 ? 's' : ''}.`,\n addConflict: (files: string[]) =>\n `The following files already exist in .claude/rules/:\\n${files.map(f => ` - ${f}`).join('\\n')}`,\n addNoRules: 'No rules specified. Use --all to add all available rules.',\n ruleNotFound: (name: string) => `Rule '${name}' not found in source.`,\n\n // Remove\n removeSuccess: (count: number) => `Removed ${count} rule${count !== 1 ? 's' : ''}.`,\n removeNotInstalled: (name: string) => `Rule '${name}' is not installed.`,\n\n // Status\n statusAllSynced: 'All rules are synced.',\n statusNeedsAttention: (count: number) =>\n `${count} rule${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} attention. Run ${formatCommand('rk pull')} to update.`,\n statusOffline: pc.dim('⚠ Could not check for updates (offline?)'),\n\n // Pull\n pullSuccess: (count: number) => `${count} rule${count !== 1 ? 's' : ''} updated.`,\n pullSkipped: (count: number) => `${count} rule${count !== 1 ? 's' : ''} skipped.`,\n pullDetached: (count: number) => `${count} rule${count !== 1 ? 's' : ''} detached.`,\n pullUpToDate: 'All rules are up to date.',\n pullDiverged: (name: string) => `${name}.md has local changes`,\n pullDivergedAndOutdated: (name: string) => `${name}.md has local changes AND source has been updated`,\n\n // Detach/Attach\n detachSuccess: (name: string) => `Rule '${name}' is now detached.`,\n detachAlready: (name: string) => `Rule '${name}' is already detached.`,\n attachSuccess: (name: string) => `Rule '${name}' is now attached.`,\n attachAlready: (name: string) => `Rule '${name}' is already attached.`,\n\n // Diff\n diffNoDifference: (name: string) => `No difference found for '${name}'.`,\n diffNoRules: 'No diverged rules to show.',\n\n // Doctor\n doctorAllGood: 'All checks passed.',\n doctorIssuesFound: (count: number) => `${count} issue${count !== 1 ? 's' : ''} found.`,\n\n // Errors\n errorGeneric: (err: string) => `Error: ${err}`,\n errorMissingSource: (name: string) => `Source file for '${name}' no longer exists.`,\n errorMissingLocal: (name: string) => `Local file for '${name}' is missing.`\n}\n","import * as p from '@clack/prompts'\nimport pc from 'picocolors'\nimport type { SourceType, PullFrequency, WindowsShell } from '../types/index.js'\n\nexport type DivergenceAction = 'overwrite' | 'detach' | 'skip' | 'cancel' | 'view-diff'\nexport type MissingSourceAction = 'keep' | 'remove'\nexport type MissingLocalAction = 'restore' | 'remove'\nexport type AttachAction = 'overwrite' | 'keep' | 'cancel'\n\nexport function isCancel(value: unknown): boolean {\n return p.isCancel(value)\n}\n\nexport async function confirmOverwrite(files: string[]): Promise<boolean> {\n const result = await p.confirm({\n message: `${files.length} file${files.length !== 1 ? 's' : ''} will be overwritten. Continue?`\n })\n\n return result === true\n}\n\nexport async function selectSourceType(): Promise<SourceType | symbol> {\n return await p.select({\n message: 'Where are your Claude rules stored?',\n options: [\n { value: 'local', label: 'Local folder', hint: 'Already cloned git repo or static folder' },\n { value: 'git', label: 'Git repository', hint: 'Clone now from URL' }\n ]\n }) as SourceType | symbol\n}\n\nexport async function inputSourcePath(): Promise<string | symbol> {\n return await p.text({\n message: 'Enter the path to your rules folder:',\n placeholder: '~/Documents/claude-rules',\n validate: (value) => {\n if (!value) return 'Path is required'\n return undefined\n }\n })\n}\n\nexport async function inputGitUrl(): Promise<string | symbol> {\n return await p.text({\n message: 'Enter the Git repository URL:',\n placeholder: 'https://github.com/adxmcollins/rulekeeper-rules.git',\n validate: (value) => {\n if (!value) return 'URL is required'\n return undefined\n }\n })\n}\n\nexport async function inputClonePath(): Promise<string | symbol> {\n return await p.text({\n message: 'Where should the repository be cloned?',\n placeholder: '~/Documents/claude-rules',\n validate: (value) => {\n if (!value) return 'Path is required'\n return undefined\n }\n })\n}\n\nexport async function selectPullFrequency(): Promise<PullFrequency | symbol> {\n return await p.select({\n message: 'How often should RuleKeeper check for updates?',\n options: [\n { value: 'daily', label: 'Daily', hint: 'Recommended' },\n { value: 'always', label: 'Always', hint: 'Every command' },\n { value: 'weekly', label: 'Weekly' },\n { value: 'never', label: 'Never', hint: 'Manual only' }\n ]\n }) as PullFrequency | symbol\n}\n\nexport async function selectWindowsShell(): Promise<WindowsShell | symbol> {\n return await p.select({\n message: 'Which shell environment are you using?',\n options: [\n { value: 'standard', label: 'Standard (CMD/PowerShell)' },\n { value: 'gitbash', label: 'Git Bash' },\n { value: 'wsl', label: 'WSL (Windows Subsystem for Linux)' }\n ]\n }) as WindowsShell | symbol\n}\n\nexport async function selectRulesToAdd(available: string[], installed: string[]): Promise<string[] | symbol> {\n const options = available.map(rule => ({\n value: rule,\n label: rule,\n hint: installed.includes(rule) ? 'already installed' : undefined\n }))\n\n return await p.multiselect({\n message: 'Select rules to add:',\n options,\n required: true\n }) as string[] | symbol\n}\n\nexport async function handleDivergedRule(\n ruleName: string,\n sourceAlsoChanged: boolean,\n isSingleRule: boolean\n): Promise<DivergenceAction | symbol> {\n const message = sourceAlsoChanged\n ? `${ruleName}.md has local changes AND source has been updated`\n : `${ruleName}.md has local changes`\n\n p.log.warn(message)\n\n const options: { value: DivergenceAction; label: string; hint: string }[] = [\n {\n value: 'overwrite',\n label: 'Overwrite',\n hint: 'Replace with source version (local changes will be lost)'\n },\n {\n value: 'detach',\n label: 'Detach',\n hint: 'Keep local version, stop tracking this rule'\n }\n ]\n\n if (sourceAlsoChanged) {\n options.push({\n value: 'view-diff',\n label: 'View diff',\n hint: 'See differences before deciding'\n })\n }\n\n options.push(\n isSingleRule\n ? { value: 'cancel', label: 'Cancel', hint: 'Abort this operation' }\n : { value: 'skip', label: 'Skip', hint: 'Do nothing for now' }\n )\n\n const action = await p.select({\n message: 'What would you like to do?',\n options\n })\n\n if (p.isCancel(action)) {\n return isSingleRule ? 'cancel' : 'skip'\n }\n\n return action as DivergenceAction\n}\n\nexport async function handleMissingSource(ruleName: string): Promise<MissingSourceAction | symbol> {\n p.log.warn(`${ruleName}.md - source file no longer exists`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'keep', label: 'Keep local', hint: 'Detach and keep the local file' },\n { value: 'remove', label: 'Remove', hint: 'Delete from project and manifest' }\n ]\n }) as MissingSourceAction | symbol\n}\n\nexport async function handleMissingLocal(ruleName: string): Promise<MissingLocalAction | symbol> {\n p.log.warn(`${ruleName}.md - local file missing`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'restore', label: 'Restore', hint: 'Copy from source' },\n { value: 'remove', label: 'Remove', hint: 'Remove from manifest' }\n ]\n }) as MissingLocalAction | symbol\n}\n\nexport async function handleAttachDiffers(ruleName: string): Promise<AttachAction | symbol> {\n p.log.warn(`${ruleName}.md differs from source version`)\n\n return await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'overwrite', label: 'Overwrite local', hint: 'Replace with source version' },\n { value: 'keep', label: 'Keep local', hint: 'Attach but keep local version (will show as diverged)' },\n { value: 'cancel', label: 'Cancel', hint: 'Keep detached' }\n ]\n }) as AttachAction | symbol\n}\n\nexport function spinner() {\n return p.spinner()\n}\n\nexport function intro(message: string) {\n p.intro(pc.bgCyan(pc.black(` ${message} `)))\n}\n\nexport function outro(message: string) {\n p.outro(message)\n}\n\nexport const log = p.log\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getOrCreateManifest,\n createRuleEntry,\n getAvailableRules,\n getRuleSourcePath,\n getClaudeDir,\n fileExists,\n copyFile,\n ensureDir,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport {\n log,\n spinner,\n isCancel,\n confirmOverwrite,\n selectRulesToAdd,\n handleDivergedRule\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface AddOptions {\n all?: boolean\n}\n\nexport async function add(rules: string[], options: AddOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop(pullResult.error ? messages.statusOffline : 'Source is up to date.')\n\n // Get available rules\n const availableRules = await getAvailableRules(config)\n if (availableRules.length === 0) {\n log.error('No rules found in source.')\n process.exit(1)\n }\n\n // Get installed rules\n const manifest = await loadManifest()\n const installedRules = manifest ? Object.keys(manifest.rules) : []\n\n // Determine which rules to add\n let rulesToAdd: string[]\n\n if (options.all) {\n rulesToAdd = availableRules.map(r => r.name)\n } else if (rules.length > 0) {\n rulesToAdd = rules\n } else {\n // Interactive selection\n const selected = await selectRulesToAdd(\n availableRules.map(r => r.name),\n installedRules\n )\n\n if (isCancel(selected)) {\n log.info('Cancelled.')\n return\n }\n\n rulesToAdd = selected as string[]\n }\n\n if (rulesToAdd.length === 0) {\n log.warn(messages.addNoRules)\n return\n }\n\n // Resolve rules case-insensitively and validate they exist\n const availableRuleNames = availableRules.map(r => r.name)\n const resolvedRules: string[] = []\n const invalidRules: string[] = []\n\n for (const rule of rulesToAdd) {\n const match = findRuleMatch(rule, availableRuleNames)\n if (match) {\n resolvedRules.push(match)\n } else {\n invalidRules.push(rule)\n }\n }\n\n if (invalidRules.length > 0) {\n for (const rule of invalidRules) {\n log.error(messages.ruleNotFound(rule))\n }\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n ensureDir(claudeDir)\n\n // Copy rules and update manifest, handling conflicts\n const updatedManifest = await getOrCreateManifest()\n let addedCount = 0\n let skippedCount = 0\n\n for (const rule of resolvedRules) {\n const sourcePath = await getRuleSourcePath(rule, config)\n if (!sourcePath) continue\n\n const filename = getRuleFilename(rule)\n const targetPath = join(claudeDir, filename)\n const sourceHash = await hashFile(sourcePath)\n\n // Check if file already exists with local changes\n if (fileExists(targetPath)) {\n const localHash = await hashFile(targetPath)\n const entry = updatedManifest.rules[rule]\n\n // If already tracked and unchanged, just update\n if (entry && localHash === entry.localHash) {\n await copyFile(sourcePath, targetPath)\n const newHash = await hashFile(targetPath)\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: newHash,\n localHash: newHash\n })\n log.success(`Updated ${filename}`)\n addedCount++\n continue\n }\n\n // If file has local changes (tracked or untracked), ask user\n if (!entry || localHash !== entry.localHash) {\n const action = await handleDivergedRule(rule, false, false)\n\n if (isCancel(action) || action === 'skip') {\n skippedCount++\n continue\n }\n\n if (action === 'detach') {\n // Keep local file, mark as detached\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: sourceHash,\n localHash: localHash,\n status: 'detached'\n })\n updatedManifest.rules[rule].detachedAt = new Date().toISOString()\n log.info(`${filename} kept as detached`)\n continue\n }\n\n // Overwrite\n }\n }\n\n try {\n await copyFile(sourcePath, targetPath)\n const hash = await hashFile(targetPath)\n\n updatedManifest.rules[rule] = createRuleEntry({\n file: filename,\n sourceHash: hash,\n localHash: hash\n })\n\n log.success(`Added ${filename}`)\n addedCount++\n } catch (error) {\n log.error(`Failed to add ${filename}: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n await saveManifest(updatedManifest)\n\n if (addedCount > 0) {\n log.info(messages.addSuccess(addedCount))\n }\n if (skippedCount > 0) {\n log.info(`${skippedCount} rule(s) skipped.`)\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getClaudeDir,\n deleteFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport { log } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface RemoveOptions {\n keepFile?: boolean\n}\n\nexport async function remove(rules: string[], options: RemoveOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n if (rules.length === 0) {\n log.error('No rules specified.')\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n const manifestRules = Object.keys(manifest.rules)\n let removedCount = 0\n\n for (const rule of rules) {\n // Case-insensitive lookup\n const match = findRuleMatch(rule, manifestRules)\n if (!match) {\n log.warn(messages.removeNotInstalled(rule))\n continue\n }\n\n const filename = getRuleFilename(match)\n const targetPath = join(claudeDir, filename)\n\n // Delete file unless --keep-file is specified\n if (!options.keepFile) {\n try {\n await deleteFile(targetPath)\n } catch (error) {\n log.warn(`Could not delete ${filename}: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n // Remove from manifest\n delete manifest.rules[match]\n log.success(`Removed ${match}`)\n removedCount++\n }\n\n await saveManifest(manifest)\n\n if (removedCount > 0) {\n log.info(messages.removeSuccess(removedCount))\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n fileExists,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename,\n isIgnoredRule\n} from '../lib/index.js'\nimport { log, spinner, formatRuleLine, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport type { RuleStatus, StatusCheckResult } from '../types/index.js'\n\nexport async function status(): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n const ruleNames = Object.keys(manifest.rules)\n if (ruleNames.length === 0) {\n log.info('No rules installed.')\n return\n }\n\n console.log('')\n console.log(formatHeader('RuleKeeper Status'))\n console.log('')\n\n const claudeDir = getClaudeDir()\n let needsAttention = 0\n\n for (const ruleName of ruleNames.sort()) {\n // Skip ignored files like README.md\n if (isIgnoredRule(ruleName)) {\n continue\n }\n\n const entry = manifest.rules[ruleName]\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n const result = await checkRuleStatus(entry, localPath, sourcePath)\n let details: string | undefined\n\n switch (result.status) {\n case 'outdated':\n details = 'source updated'\n needsAttention++\n break\n case 'diverged':\n details = 'local changes detected'\n needsAttention++\n break\n case 'detached':\n break\n case 'synced':\n break\n }\n\n if (!result.localExists) {\n details = 'local file missing'\n needsAttention++\n } else if (!result.sourceExists) {\n details = 'source file missing'\n needsAttention++\n }\n\n console.log(formatRuleLine(ruleName + '.md', result.status, details))\n }\n\n console.log('')\n\n if (needsAttention > 0) {\n log.info(messages.statusNeedsAttention(needsAttention))\n } else {\n log.success(messages.statusAllSynced)\n }\n}\n\nasync function checkRuleStatus(\n entry: { status: RuleStatus; sourceHash: string; localHash: string },\n localPath: string,\n sourcePath: string\n): Promise<StatusCheckResult> {\n const localExists = fileExists(localPath)\n const sourceExists = fileExists(sourcePath)\n\n // If detached, always return detached regardless of file state\n if (entry.status === 'detached') {\n return {\n status: 'detached',\n localChanged: false,\n sourceChanged: false,\n localExists,\n sourceExists\n }\n }\n\n // Handle missing files\n if (!localExists || !sourceExists) {\n return {\n status: 'diverged',\n localChanged: !localExists,\n sourceChanged: !sourceExists,\n localExists,\n sourceExists\n }\n }\n\n // Calculate current hashes\n const currentLocalHash = await hashFile(localPath)\n const currentSourceHash = await hashFile(sourcePath)\n\n const localChanged = currentLocalHash !== entry.localHash\n const sourceChanged = currentSourceHash !== entry.sourceHash\n\n let status: RuleStatus\n\n if (localChanged) {\n status = 'diverged'\n } else if (sourceChanged) {\n status = 'outdated'\n } else {\n status = 'synced'\n }\n\n return {\n status,\n localChanged,\n sourceChanged,\n localExists,\n sourceExists,\n currentLocalHash,\n currentSourceHash\n }\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n saveManifest,\n getClaudeDir,\n fileExists,\n copyFile,\n hashFile,\n pullSourceIfNeeded,\n updateConfigLastPull,\n getRuleFilename,\n deleteFile,\n findRuleMatch,\n isIgnoredRule\n} from '../lib/index.js'\nimport {\n log,\n spinner,\n handleDivergedRule,\n handleMissingSource,\n handleMissingLocal,\n isCancel\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { showDiff } from './diff.js'\nimport type { RuleStatus, RuleEntry } from '../types/index.js'\n\ninterface PullOptions {\n force?: boolean\n includeDetached?: boolean\n}\n\nexport async function pull(rules: string[], options: PullOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking for updates...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n // Determine which rules to process (case-insensitive matching)\n const manifestRules = Object.keys(manifest.rules)\n let rulesToProcess: string[]\n\n if (rules.length > 0) {\n rulesToProcess = []\n for (const rule of rules) {\n const match = findRuleMatch(rule, manifestRules)\n if (match) {\n rulesToProcess.push(match)\n } else {\n log.warn(`Rule '${rule}' not found in manifest`)\n }\n }\n } else {\n rulesToProcess = manifestRules\n }\n\n const results = {\n updated: [] as string[],\n skipped: [] as string[],\n detached: [] as string[],\n failed: [] as string[]\n }\n\n const claudeDir = getClaudeDir()\n const isSingleRule = rules.length === 1\n\n for (const ruleName of rulesToProcess) {\n // Skip ignored files like README.md\n if (isIgnoredRule(ruleName)) {\n continue\n }\n\n const entry = manifest.rules[ruleName]\n\n if (!entry) {\n log.warn(`Rule '${ruleName}' not found in manifest`)\n results.failed.push(ruleName)\n continue\n }\n\n // Skip detached unless explicitly included\n if (entry.status === 'detached' && !options.includeDetached) {\n log.info(`○ ${ruleName}.md (detached - skipped)`)\n results.skipped.push(ruleName)\n continue\n }\n\n const filename = getRuleFilename(ruleName)\n const sourcePath = join(config.source.path, filename)\n const localPath = join(claudeDir, filename)\n\n // Handle missing source\n if (!fileExists(sourcePath)) {\n const action = await handleMissingSource(ruleName)\n if (isCancel(action)) {\n results.skipped.push(ruleName)\n continue\n }\n\n if (action === 'keep') {\n manifest.rules[ruleName] = {\n ...entry,\n status: 'detached',\n detachedAt: new Date().toISOString()\n }\n results.detached.push(ruleName)\n } else if (action === 'remove') {\n await deleteFile(localPath)\n delete manifest.rules[ruleName]\n log.success(`Removed ${ruleName}`)\n }\n continue\n }\n\n // Handle missing local\n if (!fileExists(localPath)) {\n const action = await handleMissingLocal(ruleName)\n if (isCancel(action)) {\n results.skipped.push(ruleName)\n continue\n }\n\n if (action === 'restore') {\n await copyFile(sourcePath, localPath)\n const hash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: hash,\n localHash: hash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n log.success(`Restored ${ruleName}.md`)\n results.updated.push(ruleName)\n } else if (action === 'remove') {\n delete manifest.rules[ruleName]\n log.success(`Removed ${ruleName} from manifest`)\n }\n continue\n }\n\n // Process the rule\n const result = await pullRule(\n ruleName,\n entry,\n sourcePath,\n localPath,\n manifest,\n options,\n isSingleRule\n )\n\n switch (result) {\n case 'updated':\n log.success(`✓ ${ruleName}.md updated`)\n results.updated.push(ruleName)\n break\n case 'detached':\n log.info(`○ ${ruleName}.md detached`)\n results.detached.push(ruleName)\n break\n case 'skipped':\n results.skipped.push(ruleName)\n break\n case 'cancelled':\n await saveManifest(manifest)\n return\n }\n }\n\n await saveManifest(manifest)\n\n // Summary\n console.log('')\n if (results.updated.length > 0) {\n log.success(messages.pullSuccess(results.updated.length))\n }\n if (results.detached.length > 0) {\n log.info(messages.pullDetached(results.detached.length))\n }\n if (results.failed.length > 0) {\n log.error(`${results.failed.length} rule(s) failed`)\n }\n if (results.updated.length === 0 && results.detached.length === 0 && results.failed.length === 0) {\n log.success(messages.pullUpToDate)\n }\n}\n\nasync function pullRule(\n ruleName: string,\n entry: RuleEntry,\n sourcePath: string,\n localPath: string,\n manifest: { rules: Record<string, RuleEntry> },\n options: PullOptions,\n isSingleRule: boolean\n): Promise<'updated' | 'skipped' | 'detached' | 'cancelled'> {\n // Calculate current hashes\n const currentLocalHash = await hashFile(localPath)\n const currentSourceHash = await hashFile(sourcePath)\n\n // Determine state\n const localChanged = currentLocalHash !== entry.localHash\n const sourceChanged = currentSourceHash !== entry.sourceHash\n\n // No changes anywhere - nothing to do\n if (!localChanged && !sourceChanged) {\n return 'skipped'\n }\n\n // Only source changed - safe to update\n if (!localChanged && sourceChanged) {\n await copyFile(sourcePath, localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: currentSourceHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n }\n\n // Local changed (diverged) - need to handle\n if (localChanged) {\n // Force flag overwrites without prompting\n if (options.force) {\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: newHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n }\n\n // Interactive handling\n let action = await handleDivergedRule(ruleName, sourceChanged, isSingleRule)\n\n // Handle view-diff loop\n while (action === 'view-diff') {\n await showDiff([ruleName])\n action = await handleDivergedRule(ruleName, sourceChanged, isSingleRule)\n }\n\n if (isCancel(action)) {\n return isSingleRule ? 'cancelled' : 'skipped'\n }\n\n switch (action) {\n case 'overwrite':\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n manifest.rules[ruleName] = {\n ...entry,\n sourceHash: currentSourceHash,\n localHash: newHash,\n status: 'synced',\n updatedAt: new Date().toISOString()\n }\n return 'updated'\n\n case 'detach':\n manifest.rules[ruleName] = {\n ...entry,\n status: 'detached',\n detachedAt: new Date().toISOString()\n }\n return 'detached'\n\n case 'skip':\n case 'cancel':\n return isSingleRule ? 'cancelled' : 'skipped'\n }\n }\n\n return 'skipped'\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n fileExists,\n readTextFile,\n hashFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport {\n log,\n formatDiffAdd,\n formatDiffRemove,\n formatDiffContext,\n formatDiffHeader,\n formatPath,\n formatHeader\n} from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\ninterface DiffOptions {\n all?: boolean\n}\n\nexport async function diff(rules: string[], options: DiffOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n const claudeDir = getClaudeDir()\n\n // Determine which rules to show diff for\n let rulesToDiff: string[]\n\n if (options.all) {\n // Find all diverged rules\n rulesToDiff = []\n for (const [ruleName, entry] of Object.entries(manifest.rules)) {\n if (entry.status === 'detached') continue\n\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n\n if (!fileExists(localPath)) continue\n\n const currentLocalHash = await hashFile(localPath)\n if (currentLocalHash !== entry.localHash) {\n rulesToDiff.push(ruleName)\n }\n }\n\n if (rulesToDiff.length === 0) {\n log.info(messages.diffNoRules)\n return\n }\n } else if (rules.length > 0) {\n // Case-insensitive lookup\n const manifestRules = Object.keys(manifest.rules)\n rulesToDiff = []\n for (const rule of rules) {\n const match = findRuleMatch(rule, manifestRules)\n if (match) {\n rulesToDiff.push(match)\n } else {\n log.warn(`Rule '${rule}' not found in manifest`)\n }\n }\n } else {\n log.error('Specify a rule name or use --all to see all diverged rules.')\n process.exit(1)\n }\n\n for (const ruleName of rulesToDiff) {\n const entry = manifest.rules[ruleName]\n if (!entry) continue\n\n const filename = getRuleFilename(ruleName)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n await showRuleDiff(ruleName, sourcePath, localPath)\n }\n}\n\nexport async function showDiff(rules: string[]): Promise<void> {\n return diff(rules, {})\n}\n\nasync function showRuleDiff(\n ruleName: string,\n sourcePath: string,\n localPath: string\n): Promise<void> {\n const sourceExists = fileExists(sourcePath)\n const localExists = fileExists(localPath)\n\n console.log('')\n console.log(formatHeader(`Comparing ${ruleName}.md`))\n console.log('')\n\n if (!sourceExists && !localExists) {\n log.warn('Both source and local files are missing')\n return\n }\n\n if (!sourceExists) {\n log.warn('Source file no longer exists')\n console.log(formatDiffHeader(`--- source (missing)`))\n console.log(formatDiffHeader(`+++ local (${formatPath(localPath)})`))\n return\n }\n\n if (!localExists) {\n log.warn('Local file is missing')\n console.log(formatDiffHeader(`--- source (${formatPath(sourcePath)})`))\n console.log(formatDiffHeader(`+++ local (missing)`))\n return\n }\n\n const sourceContent = await readTextFile(sourcePath)\n const localContent = await readTextFile(localPath)\n\n if (sourceContent === localContent) {\n log.info(messages.diffNoDifference(ruleName))\n return\n }\n\n console.log(formatDiffHeader(`--- source (${sourcePath})`))\n console.log(formatDiffHeader(`+++ local (${localPath})`))\n console.log('')\n\n // Simple line-by-line diff\n const sourceLines = sourceContent.split('\\n')\n const localLines = localContent.split('\\n')\n\n const diff = computeSimpleDiff(sourceLines, localLines)\n\n for (const line of diff) {\n if (line.type === 'add') {\n console.log(formatDiffAdd(line.content))\n } else if (line.type === 'remove') {\n console.log(formatDiffRemove(line.content))\n } else {\n console.log(formatDiffContext(line.content))\n }\n }\n\n console.log('')\n}\n\ninterface DiffLine {\n type: 'add' | 'remove' | 'context'\n content: string\n}\n\nfunction computeSimpleDiff(source: string[], local: string[]): DiffLine[] {\n // Simple diff algorithm - compare lines\n const result: DiffLine[] = []\n const maxLen = Math.max(source.length, local.length)\n\n // Build a map of source lines for quick lookup\n const sourceSet = new Set(source)\n const localSet = new Set(local)\n\n let si = 0\n let li = 0\n\n while (si < source.length || li < local.length) {\n if (si >= source.length) {\n // Remaining local lines are additions\n result.push({ type: 'add', content: local[li] })\n li++\n } else if (li >= local.length) {\n // Remaining source lines are removals\n result.push({ type: 'remove', content: source[si] })\n si++\n } else if (source[si] === local[li]) {\n // Lines match\n result.push({ type: 'context', content: source[si] })\n si++\n li++\n } else if (!localSet.has(source[si])) {\n // Source line not in local - it was removed\n result.push({ type: 'remove', content: source[si] })\n si++\n } else if (!sourceSet.has(local[li])) {\n // Local line not in source - it was added\n result.push({ type: 'add', content: local[li] })\n li++\n } else {\n // Both lines exist elsewhere - treat as removal then addition\n result.push({ type: 'remove', content: source[si] })\n result.push({ type: 'add', content: local[li] })\n si++\n li++\n }\n }\n\n return result\n}\n","import {\n loadConfig,\n loadManifest,\n getAvailableRules,\n pullSourceIfNeeded,\n updateConfigLastPull\n} from '../lib/index.js'\nimport { log, spinner, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport pc from 'picocolors'\n\ninterface ListOptions {\n installed?: boolean\n}\n\nexport async function list(options: ListOptions = {}): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Pull from source if needed\n const s = spinner()\n s.start('Checking source...')\n const pullResult = await pullSourceIfNeeded(config)\n if (pullResult.pulled) {\n await updateConfigLastPull()\n }\n s.stop('')\n\n if (pullResult.error) {\n log.warn(messages.statusOffline)\n }\n\n // Get installed rules\n const manifest = await loadManifest()\n const installedRules = manifest ? Object.keys(manifest.rules) : []\n\n if (options.installed) {\n // Show only installed rules\n if (installedRules.length === 0) {\n log.info('No rules installed.')\n return\n }\n\n console.log('')\n console.log(formatHeader('Installed Rules'))\n console.log('')\n\n for (const rule of installedRules.sort()) {\n const entry = manifest!.rules[rule]\n const statusHint = entry.status !== 'synced'\n ? pc.dim(` (${entry.status})`)\n : ''\n console.log(` ${rule}.md${statusHint}`)\n }\n } else {\n // Show all available rules\n const availableRules = await getAvailableRules(config)\n\n if (availableRules.length === 0) {\n log.info('No rules found in source.')\n return\n }\n\n console.log('')\n console.log(formatHeader('Available Rules'))\n console.log('')\n\n for (const rule of availableRules.sort((a, b) => a.name.localeCompare(b.name))) {\n const installed = installedRules.includes(rule.name)\n const icon = installed ? pc.green('✓') : pc.dim('○')\n const hint = installed ? pc.dim(' (installed)') : ''\n console.log(` ${icon} ${rule.name}.md${hint}`)\n }\n\n console.log('')\n console.log(pc.dim(`Source: ${config.source.path}`))\n }\n\n console.log('')\n}\n","import {\n loadConfig,\n loadManifest,\n updateRuleInManifest,\n findRuleMatch\n} from '../lib/index.js'\nimport { log } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\nexport async function detach(ruleName: string): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Case-insensitive lookup\n const match = findRuleMatch(ruleName, Object.keys(manifest.rules))\n if (!match) {\n log.error(`Rule '${ruleName}' not found in manifest.`)\n process.exit(1)\n }\n\n const entry = manifest.rules[match]\n if (entry.status === 'detached') {\n log.warn(messages.detachAlready(match))\n return\n }\n\n await updateRuleInManifest(match, {\n status: 'detached',\n detachedAt: new Date().toISOString()\n })\n\n log.success(messages.detachSuccess(match))\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n updateRuleInManifest,\n getClaudeDir,\n fileExists,\n hashFile,\n copyFile,\n getRuleFilename,\n findRuleMatch\n} from '../lib/index.js'\nimport { log, handleAttachDiffers, isCancel } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\n\nexport async function attach(ruleName: string): Promise<void> {\n // Load config\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // Load manifest\n const manifest = await loadManifest()\n if (!manifest) {\n log.error(messages.noManifest)\n process.exit(1)\n }\n\n // Case-insensitive lookup\n const match = findRuleMatch(ruleName, Object.keys(manifest.rules))\n if (!match) {\n log.error(`Rule '${ruleName}' not found in manifest.`)\n process.exit(1)\n }\n\n const entry = manifest.rules[match]\n if (entry.status !== 'detached') {\n log.warn(messages.attachAlready(match))\n return\n }\n\n const claudeDir = getClaudeDir()\n const filename = getRuleFilename(match)\n const localPath = join(claudeDir, filename)\n const sourcePath = join(config.source.path, filename)\n\n // Check if source exists\n if (!fileExists(sourcePath)) {\n log.error(messages.errorMissingSource(match))\n process.exit(1)\n }\n\n // Check if local exists\n if (!fileExists(localPath)) {\n log.error(messages.errorMissingLocal(match))\n process.exit(1)\n }\n\n // Compare hashes\n const localHash = await hashFile(localPath)\n const sourceHash = await hashFile(sourcePath)\n\n if (localHash === sourceHash) {\n // Files match - just attach\n await updateRuleInManifest(match, {\n status: 'synced',\n sourceHash,\n localHash,\n detachedAt: undefined\n })\n log.success(messages.attachSuccess(match))\n return\n }\n\n // Files differ - ask user what to do\n const action = await handleAttachDiffers(match)\n\n if (isCancel(action)) {\n log.info('Cancelled.')\n return\n }\n\n switch (action) {\n case 'overwrite':\n await copyFile(sourcePath, localPath)\n const newHash = await hashFile(localPath)\n await updateRuleInManifest(match, {\n status: 'synced',\n sourceHash,\n localHash: newHash,\n detachedAt: undefined\n })\n log.success(messages.attachSuccess(match))\n break\n\n case 'keep':\n await updateRuleInManifest(match, {\n status: 'diverged',\n sourceHash,\n localHash,\n detachedAt: undefined\n })\n log.success(`${match} attached (will show as diverged)`)\n break\n\n case 'cancel':\n log.info('Cancelled.')\n break\n }\n}\n","import {\n loadConfig,\n saveConfig,\n expandTilde,\n fileExists,\n ensureDir,\n cloneRepo,\n pullRepo,\n isGitRepo,\n hasRemote,\n getRemoteUrl,\n isGitUrl\n} from '../lib/index.js'\nimport { log, spinner, formatPath, formatHeader } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport { join } from 'node:path'\n\nexport async function sourceShow(): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n console.log('')\n console.log(formatHeader('Source Configuration'))\n console.log('')\n console.log(` Type: ${config.source.type}`)\n console.log(` Path: ${formatPath(config.source.path)}`)\n\n if (config.source.remote) {\n console.log(` Remote: ${config.source.remote}`)\n } else if (isGitRepo(config.source.path)) {\n const remote = await getRemoteUrl(config.source.path)\n if (remote) {\n console.log(` Remote: ${remote}`)\n }\n }\n\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n if (config.settings.lastPull) {\n console.log(` Last pull: ${new Date(config.settings.lastPull).toLocaleString()}`)\n }\n console.log('')\n}\n\nexport async function sourceSet(pathOrUrl: string): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n if (isGitUrl(pathOrUrl)) {\n // It's a git URL - clone it\n const s = spinner()\n s.start('Cloning repository...')\n\n // Determine clone path from URL\n const repoName = pathOrUrl.split('/').pop()?.replace('.git', '') || 'claude-rules'\n const clonePath = expandTilde(`~/Documents/${repoName}`)\n\n try {\n ensureDir(join(clonePath, '..'))\n await cloneRepo(pathOrUrl, clonePath)\n s.stop('Repository cloned successfully.')\n\n config.source = {\n type: 'git',\n path: clonePath,\n remote: pathOrUrl\n }\n } catch (error) {\n s.stop('Failed to clone repository.')\n log.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n } else {\n // It's a local path\n const expandedPath = expandTilde(pathOrUrl)\n\n if (!fileExists(expandedPath)) {\n log.error(messages.sourceNotFound(expandedPath))\n process.exit(1)\n }\n\n config.source = {\n type: 'local',\n path: expandedPath\n }\n\n // Check if it's a git repo with a remote\n if (isGitRepo(expandedPath)) {\n const remote = await getRemoteUrl(expandedPath)\n if (remote) {\n config.source.type = 'git'\n config.source.remote = remote\n }\n }\n }\n\n await saveConfig(config)\n log.success(messages.sourceUpdated(config.source.path))\n}\n\nexport async function sourcePull(): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n if (!isGitRepo(config.source.path)) {\n log.error('Source is not a git repository.')\n process.exit(1)\n }\n\n if (!(await hasRemote(config.source.path))) {\n log.error('Source repository has no remote configured.')\n process.exit(1)\n }\n\n const s = spinner()\n s.start('Pulling from remote...')\n\n try {\n await pullRepo(config.source.path)\n s.stop('Source updated successfully.')\n\n // Update last pull time\n config.settings.lastPull = new Date().toISOString()\n await saveConfig(config)\n } catch (error) {\n s.stop('Failed to pull from remote.')\n log.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n}\n\nimport type { PullFrequency } from '../types/index.js'\n\ninterface SourceConfigOptions {\n autoPull?: boolean\n frequency?: PullFrequency\n}\n\nexport async function sourceConfig(options: SourceConfigOptions): Promise<void> {\n const config = await loadConfig()\n if (!config) {\n log.error(messages.notConfigured)\n process.exit(1)\n }\n\n // If no options provided, show current settings\n if (options.autoPull === undefined && options.frequency === undefined) {\n console.log('')\n console.log(formatHeader('Pull Settings'))\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n if (config.settings.lastPull) {\n console.log(` Last pull: ${new Date(config.settings.lastPull).toLocaleString()}`)\n }\n console.log('')\n console.log(' Use --auto-pull and --frequency to change settings.')\n console.log('')\n return\n }\n\n // Update settings\n if (options.autoPull !== undefined) {\n config.settings.autoPull = options.autoPull\n }\n\n if (options.frequency !== undefined) {\n config.settings.pullFrequency = options.frequency\n }\n\n await saveConfig(config)\n\n log.success('Settings updated.')\n console.log('')\n console.log(` Auto-pull: ${config.settings.autoPull ? 'enabled' : 'disabled'}`)\n console.log(` Frequency: ${config.settings.pullFrequency}`)\n console.log('')\n}\n","import { join } from 'node:path'\nimport {\n loadConfig,\n loadManifest,\n getClaudeDir,\n getRulekeeperDir,\n getConfigPath,\n fileExists,\n isGitRepo,\n hasRemote,\n getAvailableRules\n} from '../lib/index.js'\nimport { log, formatSuccess, formatError, formatWarning, formatHeader, formatPath } from '../ui/index.js'\nimport { messages } from '../ui/messages.js'\nimport pc from 'picocolors'\n\ninterface DiagnosticResult {\n name: string\n status: 'pass' | 'warn' | 'fail'\n message: string\n}\n\nexport async function doctor(): Promise<void> {\n console.log('')\n console.log(formatHeader('RuleKeeper Diagnostics'))\n console.log('')\n\n const results: DiagnosticResult[] = []\n\n // Check 1: Global config exists\n const configPath = getConfigPath()\n if (fileExists(configPath)) {\n results.push({\n name: 'Global config',\n status: 'pass',\n message: `Found at ${formatPath(configPath)}`\n })\n } else {\n results.push({\n name: 'Global config',\n status: 'fail',\n message: `Not found. Run ${pc.cyan('rk init')} to configure.`\n })\n }\n\n // Load config for remaining checks\n const config = await loadConfig()\n\n if (config) {\n // Check 2: Source path exists\n if (fileExists(config.source.path)) {\n results.push({\n name: 'Source path',\n status: 'pass',\n message: formatPath(config.source.path)\n })\n } else {\n results.push({\n name: 'Source path',\n status: 'fail',\n message: `Path does not exist: ${formatPath(config.source.path)}`\n })\n }\n\n // Check 3: Source has rules\n if (fileExists(config.source.path)) {\n const availableRules = await getAvailableRules(config)\n if (availableRules.length > 0) {\n results.push({\n name: 'Source rules',\n status: 'pass',\n message: `${availableRules.length} rule(s) available`\n })\n } else {\n results.push({\n name: 'Source rules',\n status: 'warn',\n message: 'No .md files found in source'\n })\n }\n }\n\n // Check 4: Git remote (if git source)\n if (config.source.type === 'git' && fileExists(config.source.path)) {\n if (isGitRepo(config.source.path)) {\n if (await hasRemote(config.source.path)) {\n results.push({\n name: 'Git remote',\n status: 'pass',\n message: 'Remote configured'\n })\n } else {\n results.push({\n name: 'Git remote',\n status: 'warn',\n message: 'No remote configured - cannot auto-pull'\n })\n }\n } else {\n results.push({\n name: 'Git repository',\n status: 'fail',\n message: 'Source is configured as git but is not a git repository'\n })\n }\n }\n }\n\n // Check 5: Project setup (only if in a project)\n const claudeDir = getClaudeDir()\n const rulekeeperDir = getRulekeeperDir()\n\n if (fileExists(claudeDir)) {\n results.push({\n name: '.claude directory',\n status: 'pass',\n message: 'Found in current project'\n })\n } else {\n results.push({\n name: '.claude directory',\n status: 'warn',\n message: 'Not found - not in a Claude Code project?'\n })\n }\n\n // Check 6: Manifest\n const manifest = await loadManifest()\n if (manifest) {\n const ruleCount = Object.keys(manifest.rules).length\n results.push({\n name: 'RuleKeeper manifest',\n status: 'pass',\n message: `${ruleCount} rule(s) tracked`\n })\n\n // Check 7: Rule file integrity\n if (config && ruleCount > 0) {\n let missingCount = 0\n for (const [ruleName, entry] of Object.entries(manifest.rules)) {\n const localPath = join(claudeDir, entry.file)\n if (!fileExists(localPath)) {\n missingCount++\n }\n }\n\n if (missingCount > 0) {\n results.push({\n name: 'Rule files',\n status: 'warn',\n message: `${missingCount} tracked rule(s) missing local files`\n })\n } else {\n results.push({\n name: 'Rule files',\n status: 'pass',\n message: 'All tracked rules have local files'\n })\n }\n }\n } else if (fileExists(claudeDir)) {\n results.push({\n name: 'RuleKeeper manifest',\n status: 'warn',\n message: `No manifest. Run ${pc.cyan('rk add')} to start tracking rules.`\n })\n }\n\n // Display results\n let passCount = 0\n let warnCount = 0\n let failCount = 0\n\n for (const result of results) {\n let icon: string\n let color: (s: string) => string\n\n switch (result.status) {\n case 'pass':\n icon = '✓'\n color = pc.green\n passCount++\n break\n case 'warn':\n icon = '⚠'\n color = pc.yellow\n warnCount++\n break\n case 'fail':\n icon = '✗'\n color = pc.red\n failCount++\n break\n }\n\n console.log(` ${color(icon)} ${result.name}: ${result.message}`)\n }\n\n console.log('')\n\n if (failCount > 0) {\n log.error(messages.doctorIssuesFound(failCount))\n } else if (warnCount > 0) {\n log.warn(`${warnCount} warning(s) found.`)\n } else {\n log.success(messages.doctorAllGood)\n }\n}\n"],"mappings":"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","names":["join","pc","parse","stringify","parse","stringify","join","readFile","join","join","status","text","pc","pc","pc","isCancel","spinner","intro","pc","outro","log","intro","log","isCancel","spinner","join","outro","pc","join","log","spinner","isCancel","join","join","log","join","join","log","spinner","join","status","join","join","log","join","diff","sourceSet","log","spinner","join","isCancel","pc","log","spinner","log","join","log","join","isCancel","join","log","spinner","join","pc","join","log","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulekeeper",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Sync and manage Claude Code rules across projects",
5
5
  "keywords": [
6
6
  "claude",