forgemap 0.1.0-dev.19-201b895 → 0.1.0-dev.21-66ff114

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
@@ -67,7 +67,7 @@ fcd kirchDev/laravel-pbac
67
67
 
68
68
  ### Real `cd` via shell integration (recommended)
69
69
 
70
- Source the shell function once:
70
+ Source the shell wrapper once:
71
71
 
72
72
  ```bash
73
73
  # zsh/bash — drop into ~/.zshrc or ~/.bashrc
@@ -77,14 +77,16 @@ eval "$(forgemap shell-init)"
77
77
  forgemap shell-init fish | source
78
78
  ```
79
79
 
80
- That defines `fcd`:
80
+ After that, `forgemap cd <slug>` actually changes directory:
81
81
 
82
82
  ```bash
83
- fcd laravel # cd straight into kirchDev/laravel-pbac (single match)
84
- fcd kirch # multiple matches → interactive picker
85
- fcd # no arg → picker over every cloned repo
83
+ forgemap cd laravel # cd straight into kirchDev/laravel-pbac (single match)
84
+ forgemap cd kirch # multiple matches → interactive picker
85
+ forgemap cd # no arg → picker over every cloned repo
86
86
  ```
87
87
 
88
+ All other `forgemap` subcommands pass through to the real binary unchanged.
89
+
88
90
  ### Search and pick on demand
89
91
 
90
92
  ```bash
@@ -94,12 +96,15 @@ forgemap pick # interactive picker (consola prompt)
94
96
  forgemap pick kirch # picker pre-filtered by fuzzy query
95
97
  ```
96
98
 
97
- > [!TIP]
98
- > In a TTY, `forgemap search --format pretty` wraps each path as an OSC 8
99
- > hyperlink. Cmd/Ctrl-clickable in iTerm2, WezTerm, Kitty, Windows
100
- > Terminal, and the VS Code terminal — others just show the visible
101
- > text. On WSL2, paths are translated to `\\wsl$\<distro>\…` so Windows
102
- > Explorer can follow the click.
99
+ ### Open the folder in the OS file manager
100
+
101
+ ```bash
102
+ forgemap open kirchDev/laravel-pbac
103
+ ```
104
+
105
+ - **WSL** → launches `explorer.exe` against `\\wsl$\<distro>\…`, Explorer opens the folder
106
+ - **macOS** → `open <path>` (Finder)
107
+ - **Linux** → `xdg-open <path>`
103
108
 
104
109
  ## ⚙️ Configuration
105
110
 
@@ -1,14 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
  import { defineCommand, runMain } from "citty";
3
+ import consola from "consola";
3
4
  import { existsSync } from "node:fs";
4
5
  import { mkdir, writeFile, readdir } from "node:fs/promises";
5
- import consola from "consola";
6
6
  import { dirname, isAbsolute, resolve, join } from "pathe";
7
7
  import { loadConfig } from "c12";
8
8
  import { spawn } from "node:child_process";
9
9
  import { homedir } from "node:os";
10
10
  import { colors, formatTree } from "consola/utils";
11
11
  import Fuse from "fuse.js";
12
+ const cdCommand = defineCommand({
13
+ meta: {
14
+ name: "cd",
15
+ description: "Change directory into a repo (requires shell integration)"
16
+ },
17
+ args: {
18
+ slug: {
19
+ type: "positional",
20
+ description: "owner/repo, forge:owner/repo, full URL, or fuzzy query",
21
+ required: false
22
+ }
23
+ },
24
+ async run() {
25
+ consola.error(
26
+ "forgemap cd needs shell integration to actually change directory."
27
+ );
28
+ consola.info("Source the wrapper once and try again:");
29
+ consola.info(' eval "$(forgemap shell-init)" # zsh/bash');
30
+ consola.info(" forgemap shell-init fish | source # fish");
31
+ consola.info(
32
+ "Or, if you just want the path on stdout, use: forgemap path <slug>"
33
+ );
34
+ process.exitCode = 1;
35
+ }
36
+ });
12
37
  const DEFAULT_CONFIG = {
13
38
  root: ".",
14
39
  defaultForge: "github",
@@ -351,6 +376,61 @@ const configCommand = defineCommand({
351
376
  show: configShowCommand
352
377
  }
353
378
  });
379
+ function platformOpen(localPath) {
380
+ const distro = process.env.WSL_DISTRO_NAME;
381
+ if (distro) {
382
+ const winPath = `\\\\wsl$\\${distro}${localPath.replaceAll("/", "\\")}`;
383
+ return { cmd: "explorer.exe", args: [winPath] };
384
+ }
385
+ if (process.platform === "darwin") {
386
+ return { cmd: "open", args: [localPath] };
387
+ }
388
+ return { cmd: "xdg-open", args: [localPath] };
389
+ }
390
+ const openCommand = defineCommand({
391
+ meta: {
392
+ name: "open",
393
+ description: "Open a repo in the OS file manager (Explorer on WSL, Finder on macOS, xdg-open elsewhere)"
394
+ },
395
+ args: {
396
+ slug: {
397
+ type: "positional",
398
+ description: "owner/repo, forge:owner/repo, or full URL",
399
+ required: true
400
+ },
401
+ config: {
402
+ type: "string",
403
+ description: "Path to forgemap.config.ts (overrides walk-up discovery)"
404
+ }
405
+ },
406
+ async run({ args }) {
407
+ const loaded = await loadForgeMapConfig({ configFile: args.config });
408
+ const parsed = parseSlug(args.slug);
409
+ const configDir = loaded.configFile ? dirname(loaded.configFile) : loaded.cwd;
410
+ const resolved = resolveSlug(parsed, {
411
+ config: loaded.config,
412
+ configDir
413
+ });
414
+ const { cmd, args: cmdArgs } = platformOpen(resolved.localPath);
415
+ consola.info(`Opening ${resolved.localPath}`);
416
+ const child = spawn(cmd, cmdArgs, {
417
+ stdio: "ignore",
418
+ detached: true
419
+ });
420
+ child.on("error", (error) => {
421
+ if (error.code === "ENOENT") {
422
+ consola.error(
423
+ `Could not find \`${cmd}\`. Install it (or open the path manually).`
424
+ );
425
+ process.exitCode = 1;
426
+ } else {
427
+ consola.error(error.message);
428
+ process.exitCode = 1;
429
+ }
430
+ });
431
+ child.unref();
432
+ }
433
+ });
354
434
  const pathCommand = defineCommand({
355
435
  meta: {
356
436
  name: "path",
@@ -476,16 +556,6 @@ const pickCommand = defineCommand({
476
556
  }
477
557
  }
478
558
  });
479
- function toFileUrl(absolutePath) {
480
- const distro = process.env.WSL_DISTRO_NAME;
481
- if (distro) {
482
- return `file:////wsl$/${distro}${absolutePath}`;
483
- }
484
- return `file://${absolutePath}`;
485
- }
486
- function osc8(url, text) {
487
- return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
488
- }
489
559
  function renderTree(repos) {
490
560
  const groups = /* @__PURE__ */ new Map();
491
561
  for (const r of repos) {
@@ -497,7 +567,7 @@ function renderTree(repos) {
497
567
  Array.from(groups, ([forge, items]) => ({
498
568
  text: colors.bold(forge),
499
569
  children: items.map((r) => ({
500
- text: `${colors.cyan(r.slug)} ${osc8(toFileUrl(r.localPath), colors.dim(r.localPath))}`
570
+ text: `${colors.cyan(r.slug)} ${colors.dim(r.localPath)}`
501
571
  }))
502
572
  }))
503
573
  );
@@ -574,68 +644,73 @@ function detectShell() {
574
644
  if (env.endsWith("/bash")) return "bash";
575
645
  return "zsh";
576
646
  }
577
- function renderPosix(fnName) {
647
+ function renderPosix(name) {
578
648
  return `# forgemap shell integration — drop into your ~/.zshrc / ~/.bashrc:
579
649
  # eval "$(forgemap shell-init)"
650
+ #
651
+ # Wraps the forgemap binary so that \`${name} cd <slug>\` actually changes
652
+ # directory in this shell. All other subcommands fall through unchanged.
580
653
 
581
- ${fnName}() {
582
- if [ "$#" -eq 0 ]; then
654
+ ${name}() {
655
+ if [ "$1" = "cd" ]; then
656
+ shift
583
657
  local target
584
- target=$(forgemap pick) || return $?
585
- [ -n "$target" ] && cd "$target"
658
+ if [ "$#" -eq 0 ]; then
659
+ target=$(command forgemap pick) || return $?
660
+ else
661
+ local matches
662
+ matches=$(command forgemap search "$1" --format path)
663
+ local count
664
+ count=$(printf '%s' "$matches" | grep -c '^/' || true)
665
+ if [ "$count" = "1" ]; then
666
+ target="$matches"
667
+ elif [ "$count" = "0" ]; then
668
+ echo "forgemap cd: no match for $1" >&2
669
+ return 1
670
+ else
671
+ target=$(command forgemap pick "$1") || return $?
672
+ fi
673
+ fi
674
+ [ -n "$target" ] && builtin cd "$target"
586
675
  return
587
676
  fi
588
- local matches
589
- matches=$(forgemap search "$1" --format path)
590
- if [ -z "$matches" ]; then
591
- echo "forgemap: no match for $1" >&2
592
- return 1
593
- fi
594
- local count
595
- count=$(printf '%s\\n' "$matches" | wc -l | tr -d ' ')
596
- if [ "$count" = "1" ]; then
597
- cd "$matches"
598
- else
599
- local target
600
- target=$(forgemap pick "$1") || return $?
601
- [ -n "$target" ] && cd "$target"
602
- fi
677
+ command forgemap "$@"
603
678
  }
604
679
  `;
605
680
  }
606
- function renderFish(fnName) {
681
+ function renderFish(name) {
607
682
  return `# forgemap shell integration — drop into your ~/.config/fish/config.fish:
608
683
  # forgemap shell-init fish | source
609
684
 
610
- function ${fnName}
611
- if test (count $argv) -eq 0
612
- set target (forgemap pick); or return $status
613
- if test -n "$target"
614
- cd "$target"
685
+ function ${name} --description "forgemap with cd interception"
686
+ if test (count $argv) -ge 1 -a "$argv[1]" = "cd"
687
+ set --erase argv[1]
688
+ set target ""
689
+ if test (count $argv) -eq 0
690
+ set target (command forgemap pick); or return $status
691
+ else
692
+ set matches (command forgemap search $argv[1] --format path)
693
+ set count (count $matches)
694
+ if test $count -eq 1
695
+ set target $matches[1]
696
+ else if test $count -eq 0
697
+ echo "forgemap cd: no match for $argv[1]" >&2
698
+ return 1
699
+ else
700
+ set target (command forgemap pick $argv[1]); or return $status
701
+ end
615
702
  end
703
+ test -n "$target"; and builtin cd $target
616
704
  return
617
705
  end
618
- set matches (forgemap search $argv[1] --format path)
619
- if test -z "$matches"
620
- echo "forgemap: no match for $argv[1]" >&2
621
- return 1
622
- end
623
- set count (count $matches)
624
- if test $count -eq 1
625
- cd $matches[1]
626
- else
627
- set target (forgemap pick $argv[1]); or return $status
628
- if test -n "$target"
629
- cd "$target"
630
- end
631
- end
706
+ command forgemap $argv
632
707
  end
633
708
  `;
634
709
  }
635
710
  const shellInitCommand = defineCommand({
636
711
  meta: {
637
712
  name: "shell-init",
638
- description: 'Print a shell function (fcd) that resolves and cd-s into a repo. Source it via `eval "$(forgemap shell-init)"`.'
713
+ description: 'Print a shell wrapper that adds `forgemap cd <slug>` as a real cd. Source it via `eval "$(forgemap shell-init)"`.'
639
714
  },
640
715
  args: {
641
716
  shell: {
@@ -645,8 +720,8 @@ const shellInitCommand = defineCommand({
645
720
  },
646
721
  name: {
647
722
  type: "string",
648
- description: "Name of the generated shell function",
649
- default: "fcd"
723
+ description: "Name of the generated wrapper function (default: forgemap)",
724
+ default: "forgemap"
650
725
  }
651
726
  },
652
727
  async run({ args }) {
@@ -658,8 +733,8 @@ const shellInitCommand = defineCommand({
658
733
  process.exitCode = 1;
659
734
  return;
660
735
  }
661
- const fnName = args.name || "fcd";
662
- const out = requested === "fish" ? renderFish(fnName) : renderPosix(fnName);
736
+ const name = args.name || "forgemap";
737
+ const out = requested === "fish" ? renderFish(name) : renderPosix(name);
663
738
  process.stdout.write(out);
664
739
  }
665
740
  });
@@ -670,7 +745,9 @@ const rootCommand = defineCommand({
670
745
  },
671
746
  subCommands: {
672
747
  clone: cloneCommand,
748
+ cd: cdCommand,
673
749
  path: pathCommand,
750
+ open: openCommand,
674
751
  search: searchCommand,
675
752
  pick: pickCommand,
676
753
  "shell-init": shellInitCommand,
@@ -1 +1 @@
1
- {"version":3,"file":"forgemap.mjs","sources":["../../src/config/load.ts","../../src/utils/exec.ts","../../src/forges/github.ts","../../src/forges/registry.ts","../../src/slug/parse.ts","../../src/utils/path.ts","../../src/slug/resolve.ts","../../src/commands/clone.ts","../../src/commands/config/init.ts","../../src/commands/config/show.ts","../../src/commands/config/index.ts","../../src/commands/path.ts","../../src/repos/scan.ts","../../src/commands/pick.ts","../../src/utils/wsl.ts","../../src/commands/search.ts","../../src/commands/shell-init.ts","../../src/cli.ts","../../src/bin/forgemap.ts"],"sourcesContent":["import { loadConfig } from 'c12';\nimport { dirname } from 'pathe';\nimport type { ForgeMapConfig, ForgeMapUserConfig } from './schema.ts';\n\nexport interface LoadedConfig {\n config: ForgeMapConfig;\n configFile: string | undefined;\n cwd: string;\n}\n\nconst DEFAULT_CONFIG: ForgeMapConfig = {\n root: '.',\n defaultForge: 'github',\n forges: {\n github: {\n type: 'github',\n host: 'github.com',\n dir: 'comGithub'\n }\n }\n};\n\nexport interface LoadOptions {\n cwd?: string;\n configFile?: string;\n}\n\nexport async function loadForgeMapConfig(\n options: LoadOptions = {}\n): Promise<LoadedConfig> {\n const envConfig = process.env.FORGEMAP_CONFIG;\n const explicit = options.configFile ?? envConfig;\n const cwd = explicit ? dirname(explicit) : (options.cwd ?? process.cwd());\n\n const { config, configFile } = await loadConfig<ForgeMapUserConfig>({\n name: 'forgemap',\n cwd,\n configFile: explicit ? explicit : 'forgemap.config',\n rcFile: false,\n globalRc: false,\n dotenv: false,\n defaults: DEFAULT_CONFIG\n });\n\n const merged: ForgeMapConfig = {\n root: config.root ?? DEFAULT_CONFIG.root,\n defaultForge: config.defaultForge ?? DEFAULT_CONFIG.defaultForge,\n forges: {\n ...DEFAULT_CONFIG.forges,\n ...config.forges\n }\n };\n\n return {\n config: merged,\n configFile: configFile || undefined,\n cwd\n };\n}\n","import { spawn } from 'node:child_process';\n\nexport interface ExecResult {\n code: number;\n}\n\nexport function execInherit(\n command: string,\n args: string[]\n): Promise<ExecResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(command, args, { stdio: 'inherit' });\n child.on('error', rejectPromise);\n child.on('close', (code) => {\n resolvePromise({ code: code ?? 0 });\n });\n });\n}\n\nexport function hasCommand(command: string): Promise<boolean> {\n return new Promise((resolvePromise) => {\n const child = spawn(\n process.platform === 'win32' ? 'where' : 'which',\n [command],\n {\n stdio: 'ignore'\n }\n );\n child.on('error', () => resolvePromise(false));\n child.on('close', (code) => resolvePromise(code === 0));\n });\n}\n","import { execInherit, hasCommand } from '../utils/exec.ts';\nimport type { CloneOptions, ForgeAdapter } from './types.ts';\n\nexport const githubAdapter: ForgeAdapter = {\n async clone({ owner, repo, dest }: CloneOptions) {\n if (!(await hasCommand('gh'))) {\n throw new Error(\n 'GitHub CLI (`gh`) is not installed. Install it from https://cli.github.com/ and run `gh auth login`.'\n );\n }\n const { code } = await execInherit('gh', [\n 'repo',\n 'clone',\n `${owner}/${repo}`,\n dest\n ]);\n if (code !== 0) {\n throw new Error(`gh repo clone exited with code ${code}`);\n }\n }\n};\n","import type { ForgeType } from '../config/schema.ts';\nimport { githubAdapter } from './github.ts';\nimport type { ForgeAdapter } from './types.ts';\n\nexport function getForgeAdapter(type: ForgeType): ForgeAdapter {\n switch (type) {\n case 'github':\n return githubAdapter;\n case 'gitlab':\n case 'gitea':\n case 'codeberg':\n throw new Error(\n `Forge type \"${type}\" is not implemented yet. Only \"github\" is supported in this release.`\n );\n default: {\n const exhaustive: never = type;\n throw new Error(`Unknown forge type: ${String(exhaustive)}`);\n }\n }\n}\n","export interface ParsedSlug {\n /** Forge alias if explicitly specified via `<forge>:<owner>/<repo>` */\n forgeName?: string;\n /** Host if extracted from URL/SSH form */\n host?: string;\n owner: string;\n repo: string;\n}\n\nconst SHORT_RE = /^([\\w.-]+)\\/([\\w.-]+)$/;\nconst NAMED_RE = /^([\\w.-]+):([\\w.-]+)\\/([\\w.-]+)$/;\nconst SSH_RE = /^git@([\\w.-]+):([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?$/;\n\nfunction stripGitSuffix(repo: string): string {\n return repo.endsWith('.git') ? repo.slice(0, -4) : repo;\n}\n\nexport function parseSlug(input: string): ParsedSlug {\n const trimmed = input.trim();\n if (!trimmed) {\n throw new Error('Slug is empty');\n }\n\n // git@host:owner/repo(.git)\n const ssh = SSH_RE.exec(trimmed);\n if (ssh) {\n return {\n host: ssh[1],\n owner: ssh[2]!,\n repo: stripGitSuffix(ssh[3]!)\n };\n }\n\n // https://host/owner/repo(.git) or http://...\n if (/^https?:\\/\\//.test(trimmed)) {\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n throw new Error(`Invalid URL: ${trimmed}`);\n }\n const segments = url.pathname.split('/').filter(Boolean);\n if (segments.length < 2) {\n throw new Error(`URL must contain owner and repo: ${trimmed}`);\n }\n return {\n host: url.host,\n owner: segments[0]!,\n repo: stripGitSuffix(segments[1]!)\n };\n }\n\n // forge:owner/repo\n const named = NAMED_RE.exec(trimmed);\n if (named) {\n return {\n forgeName: named[1],\n owner: named[2]!,\n repo: stripGitSuffix(named[3]!)\n };\n }\n\n // owner/repo\n const short = SHORT_RE.exec(trimmed);\n if (short) {\n return {\n owner: short[1]!,\n repo: stripGitSuffix(short[2]!)\n };\n }\n\n throw new Error(`Unrecognized slug format: ${input}`);\n}\n","import { homedir } from 'node:os';\nimport { isAbsolute, resolve } from 'pathe';\n\nexport function expandTilde(p: string): string {\n if (p === '~') return homedir();\n if (p.startsWith('~/')) return resolve(homedir(), p.slice(2));\n return p;\n}\n\nexport function resolveRoot(root: string, configDir: string): string {\n const expanded = expandTilde(root);\n if (isAbsolute(expanded)) return expanded;\n return resolve(configDir, expanded);\n}\n","import { join } from 'pathe';\nimport type { ForgeConfig, ForgeMapConfig } from '../config/schema.ts';\nimport { resolveRoot } from '../utils/path.ts';\nimport type { ParsedSlug } from './parse.ts';\n\nexport interface ResolvedSlug {\n forgeName: string;\n forge: ForgeConfig;\n owner: string;\n repo: string;\n localPath: string;\n}\n\nexport interface ResolveOptions {\n config: ForgeMapConfig;\n configDir: string;\n}\n\nfunction findForgeByHost(\n forges: ForgeMapConfig['forges'],\n host: string\n): { name: string; forge: ForgeConfig } | undefined {\n for (const [name, forge] of Object.entries(forges)) {\n if (forge.host.toLowerCase() === host.toLowerCase()) {\n return { name, forge };\n }\n }\n return undefined;\n}\n\nexport function resolveSlug(\n parsed: ParsedSlug,\n options: ResolveOptions\n): ResolvedSlug {\n const { config, configDir } = options;\n\n let forgeName: string;\n let forge: ForgeConfig;\n\n if (parsed.forgeName) {\n const candidate = config.forges[parsed.forgeName];\n if (!candidate) {\n throw new Error(\n `Forge \"${parsed.forgeName}\" is not defined in forgemap.config`\n );\n }\n forgeName = parsed.forgeName;\n forge = candidate;\n } else if (parsed.host) {\n const match = findForgeByHost(config.forges, parsed.host);\n if (!match) {\n throw new Error(\n `No forge configured for host \"${parsed.host}\". Add it to forgemap.config.ts.`\n );\n }\n forgeName = match.name;\n forge = match.forge;\n } else {\n const candidate = config.forges[config.defaultForge];\n if (!candidate) {\n throw new Error(\n `Default forge \"${config.defaultForge}\" is not defined in forgemap.config`\n );\n }\n forgeName = config.defaultForge;\n forge = candidate;\n }\n\n const root = resolveRoot(config.root, configDir);\n const localPath = join(root, forge.dir, parsed.owner, parsed.repo);\n\n return {\n forgeName,\n forge,\n owner: parsed.owner,\n repo: parsed.repo,\n localPath\n };\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { getForgeAdapter } from '../forges/registry.ts';\nimport { parseSlug } from '../slug/parse.ts';\nimport { resolveSlug } from '../slug/resolve.ts';\n\nexport const cloneCommand = defineCommand({\n meta: {\n name: 'clone',\n description: 'Clone a repo into the configured local layout'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, or full URL',\n required: true\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const parsed = parseSlug(args.slug);\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const resolved = resolveSlug(parsed, {\n config: loaded.config,\n configDir\n });\n\n if (existsSync(resolved.localPath)) {\n consola.info(`Already cloned at ${resolved.localPath}`);\n return;\n }\n\n await mkdir(dirname(resolved.localPath), { recursive: true });\n\n const adapter = getForgeAdapter(resolved.forge.type);\n await adapter.clone({\n forge: resolved.forge,\n owner: resolved.owner,\n repo: resolved.repo,\n dest: resolved.localPath\n });\n\n consola.success(\n `Cloned ${resolved.owner}/${resolved.repo} → ${resolved.localPath}`\n );\n }\n});\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { dirname, join, resolve } from 'pathe';\n\nconst TEMPLATE = `/**\n * forgemap configuration.\n *\n * For type-safe authoring, install forgemap and switch to:\n * import { defineForgeMapConfig } from 'forgemap/config';\n * export default defineForgeMapConfig({ ... });\n *\n * @type {import('forgemap').ForgeMapUserConfig}\n */\nexport default {\n root: '.',\n defaultForge: 'github',\n forges: {\n github: {\n type: 'github',\n host: 'github.com',\n dir: 'comGithub'\n }\n }\n};\n`;\n\nexport const configInitCommand = defineCommand({\n meta: {\n name: 'init',\n description:\n 'Create a forgemap.config.ts in the current (or given) directory'\n },\n args: {\n out: {\n type: 'string',\n description: 'Directory to write forgemap.config.ts into',\n default: '.'\n },\n force: {\n type: 'boolean',\n description: 'Overwrite if forgemap.config.ts already exists',\n default: false\n }\n },\n async run({ args }) {\n const outDir = resolve(process.cwd(), args.out);\n const target = join(outDir, 'forgemap.config.ts');\n\n await mkdir(dirname(target), { recursive: true });\n\n try {\n await writeFile(target, TEMPLATE, {\n encoding: 'utf8',\n flag: args.force ? 'w' : 'wx'\n });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n consola.error(`${target} already exists. Use --force to overwrite.`);\n process.exitCode = 1;\n return;\n }\n throw error;\n }\n\n consola.success(`Wrote ${target}`);\n }\n});\n","import { defineCommand } from 'citty';\nimport { loadForgeMapConfig } from '../../config/load.ts';\n\nexport const configShowCommand = defineCommand({\n meta: {\n name: 'show',\n description: 'Print the resolved forgemap config and its source path'\n },\n args: {\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n process.stdout.write(\n JSON.stringify(\n {\n configFile: loaded.configFile ?? null,\n cwd: loaded.cwd,\n config: loaded.config\n },\n null,\n 2\n ) + '\\n'\n );\n }\n});\n","import { defineCommand } from 'citty';\nimport { configInitCommand } from './init.ts';\nimport { configShowCommand } from './show.ts';\n\nexport const configCommand = defineCommand({\n meta: {\n name: 'config',\n description: 'Manage the forgemap config file'\n },\n subCommands: {\n init: configInitCommand,\n show: configShowCommand\n }\n});\n","import { defineCommand } from 'citty';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { dirname } from 'pathe';\nimport { parseSlug } from '../slug/parse.ts';\nimport { resolveSlug } from '../slug/resolve.ts';\n\nexport const pathCommand = defineCommand({\n meta: {\n name: 'path',\n description: 'Print the local path where a repo lives (or would live)'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, or full URL',\n required: true\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const parsed = parseSlug(args.slug);\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const resolved = resolveSlug(parsed, {\n config: loaded.config,\n configDir\n });\n process.stdout.write(`${resolved.localPath}\\n`);\n }\n});\n","import { readdir } from 'node:fs/promises';\nimport { join } from 'pathe';\nimport type { ForgeConfig, ForgeMapConfig } from '../config/schema.ts';\nimport { resolveRoot } from '../utils/path.ts';\n\nexport interface ScannedRepo {\n forgeName: string;\n forge: ForgeConfig;\n owner: string;\n repo: string;\n localPath: string;\n /** Convenience: `<owner>/<repo>` */\n slug: string;\n}\n\nasync function listDirs(path: string): Promise<string[]> {\n try {\n const entries = await readdir(path, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => e.name);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw error;\n }\n}\n\nexport interface ScanOptions {\n config: ForgeMapConfig;\n configDir: string;\n}\n\nexport async function scanRepos(options: ScanOptions): Promise<ScannedRepo[]> {\n const { config, configDir } = options;\n const root = resolveRoot(config.root, configDir);\n const repos: ScannedRepo[] = [];\n\n for (const [forgeName, forge] of Object.entries(config.forges)) {\n const forgeRoot = join(root, forge.dir);\n const owners = await listDirs(forgeRoot);\n for (const owner of owners) {\n const ownerPath = join(forgeRoot, owner);\n const repoNames = await listDirs(ownerPath);\n for (const repo of repoNames) {\n repos.push({\n forgeName,\n forge,\n owner,\n repo,\n localPath: join(ownerPath, repo),\n slug: `${owner}/${repo}`\n });\n }\n }\n }\n\n return repos;\n}\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { colors } from 'consola/utils';\nimport Fuse from 'fuse.js';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { type ScannedRepo, scanRepos } from '../repos/scan.ts';\n\nexport const pickCommand = defineCommand({\n meta: {\n name: 'pick',\n description:\n 'Interactively pick a cloned repo from the configured layout and print its path'\n },\n args: {\n query: {\n type: 'positional',\n description: 'Optional fuzzy filter applied before showing the picker',\n required: false\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const all = await scanRepos({ config: loaded.config, configDir });\n\n let candidates: ScannedRepo[];\n if (args.query) {\n const fuse = new Fuse(all, {\n keys: ['slug', 'owner', 'repo'],\n threshold: 0.3,\n ignoreLocation: true\n });\n candidates = fuse.search(args.query).map((r) => r.item);\n } else {\n candidates = all;\n }\n\n if (candidates.length === 0) {\n consola.error(\n args.query\n ? `No repos match \"${args.query}\".`\n : 'No repos found under the configured root.'\n );\n process.exitCode = 1;\n return;\n }\n\n if (candidates.length === 1) {\n process.stdout.write(`${candidates[0]!.localPath}\\n`);\n return;\n }\n\n if (!process.stdin.isTTY) {\n consola.error(\n 'pick requires an interactive terminal. Use `forgemap search` for non-interactive output.'\n );\n process.exitCode = 1;\n return;\n }\n\n const choice = await consola.prompt('Select a repo', {\n type: 'select',\n options: candidates.map((r) => ({\n label: `${colors.gray(`${r.forgeName}:`)}${r.slug}`,\n value: r.localPath,\n hint: r.localPath\n }))\n });\n\n if (typeof choice === 'string' && choice) {\n process.stdout.write(`${choice}\\n`);\n }\n }\n});\n","/**\n * Build a `file://` URL that opens in the host OS, with WSL2 awareness.\n *\n * On WSL2, plain `file:///root/foo` points at the WSL filesystem from\n * Windows's point of view — clicking from Windows Terminal won't open\n * anything. We translate the path into the UNC form Windows can follow:\n * `\\\\wsl$\\<distro>\\root\\foo`, rendered as `file:////wsl$/<distro>/...`\n * (the 4-slash form: scheme + empty authority + UNC path).\n *\n * Outside WSL, returns plain `file://<absolute-path>`.\n */\nexport function isWsl(): boolean {\n return Boolean(process.env.WSL_DISTRO_NAME);\n}\n\nexport function toFileUrl(absolutePath: string): string {\n const distro = process.env.WSL_DISTRO_NAME;\n if (distro) {\n return `file:////wsl$/${distro}${absolutePath}`;\n }\n return `file://${absolutePath}`;\n}\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { colors, formatTree } from 'consola/utils';\nimport Fuse from 'fuse.js';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { type ScannedRepo, scanRepos } from '../repos/scan.ts';\nimport { toFileUrl } from '../utils/wsl.ts';\n\ntype Format = 'auto' | 'pretty' | 'path' | 'slug';\n\n/**\n * OSC 8 hyperlink. Modern terminals (iTerm2, WezTerm, Kitty, Windows\n * Terminal, GNOME Terminal, VS Code) render it as a clickable link; old\n * ones just show the visible text.\n */\nfunction osc8(url: string, text: string): string {\n return `\\x1b]8;;${url}\\x07${text}\\x1b]8;;\\x07`;\n}\n\nfunction renderTree(repos: ScannedRepo[]): string {\n const groups = new Map<string, ScannedRepo[]>();\n for (const r of repos) {\n const list = groups.get(r.forgeName);\n if (list) list.push(r);\n else groups.set(r.forgeName, [r]);\n }\n\n return formatTree(\n Array.from(groups, ([forge, items]) => ({\n text: colors.bold(forge),\n children: items.map((r) => ({\n text: `${colors.cyan(r.slug)} ${osc8(toFileUrl(r.localPath), colors.dim(r.localPath))}`\n }))\n }))\n );\n}\n\nexport const searchCommand = defineCommand({\n meta: {\n name: 'search',\n description:\n 'Fuzzy-search cloned repos by owner/repo and print matching repos'\n },\n args: {\n query: {\n type: 'positional',\n description: 'Search term (matched fuzzily against <owner>/<repo>)',\n required: true\n },\n format: {\n type: 'string',\n description:\n 'Output format: auto (default), pretty, path, or slug. auto picks pretty in a TTY, path when piped.',\n default: 'auto'\n },\n limit: {\n type: 'string',\n description: 'Maximum number of matches to print (default: unlimited)'\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const repos = await scanRepos({ config: loaded.config, configDir });\n\n const fuse = new Fuse(repos, {\n keys: ['slug', 'owner', 'repo'],\n threshold: 0.3,\n ignoreLocation: true,\n includeScore: true\n });\n\n const limit = args.limit ? Number.parseInt(args.limit, 10) : undefined;\n const results = fuse.search(args.query, limit ? { limit } : undefined);\n const items = results.map((r) => r.item);\n\n const allowed: Format[] = ['auto', 'pretty', 'path', 'slug'];\n if (!allowed.includes(args.format as Format)) {\n consola.error(\n `Invalid --format value \"${args.format}\". Allowed: ${allowed.join(', ')}.`\n );\n process.exitCode = 1;\n return;\n }\n const requested = args.format as Format;\n const format: Exclude<Format, 'auto'> =\n requested === 'auto'\n ? process.stdout.isTTY\n ? 'pretty'\n : 'path'\n : requested;\n\n if (items.length === 0) {\n if (format === 'pretty') consola.info(`No matches for \"${args.query}\".`);\n return;\n }\n\n if (format === 'pretty') {\n process.stdout.write(`${renderTree(items)}\\n`);\n return;\n }\n\n for (const item of items) {\n process.stdout.write(\n `${format === 'slug' ? item.slug : item.localPath}\\n`\n );\n }\n }\n});\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\n\ntype Shell = 'zsh' | 'bash' | 'fish';\n\nconst SUPPORTED: Shell[] = ['zsh', 'bash', 'fish'];\n\nfunction detectShell(): Shell {\n const env = process.env.SHELL ?? '';\n if (env.endsWith('/fish')) return 'fish';\n if (env.endsWith('/bash')) return 'bash';\n return 'zsh';\n}\n\nfunction renderPosix(fnName: string): string {\n return `# forgemap shell integration — drop into your ~/.zshrc / ~/.bashrc:\n# eval \"$(forgemap shell-init)\"\n\n${fnName}() {\n if [ \"$#\" -eq 0 ]; then\n local target\n target=$(forgemap pick) || return $?\n [ -n \"$target\" ] && cd \"$target\"\n return\n fi\n local matches\n matches=$(forgemap search \"$1\" --format path)\n if [ -z \"$matches\" ]; then\n echo \"forgemap: no match for $1\" >&2\n return 1\n fi\n local count\n count=$(printf '%s\\\\n' \"$matches\" | wc -l | tr -d ' ')\n if [ \"$count\" = \"1\" ]; then\n cd \"$matches\"\n else\n local target\n target=$(forgemap pick \"$1\") || return $?\n [ -n \"$target\" ] && cd \"$target\"\n fi\n}\n`;\n}\n\nfunction renderFish(fnName: string): string {\n return `# forgemap shell integration — drop into your ~/.config/fish/config.fish:\n# forgemap shell-init fish | source\n\nfunction ${fnName}\n if test (count $argv) -eq 0\n set target (forgemap pick); or return $status\n if test -n \"$target\"\n cd \"$target\"\n end\n return\n end\n set matches (forgemap search $argv[1] --format path)\n if test -z \"$matches\"\n echo \"forgemap: no match for $argv[1]\" >&2\n return 1\n end\n set count (count $matches)\n if test $count -eq 1\n cd $matches[1]\n else\n set target (forgemap pick $argv[1]); or return $status\n if test -n \"$target\"\n cd \"$target\"\n end\n end\nend\n`;\n}\n\nexport const shellInitCommand = defineCommand({\n meta: {\n name: 'shell-init',\n description:\n 'Print a shell function (fcd) that resolves and cd-s into a repo. Source it via `eval \"$(forgemap shell-init)\"`.'\n },\n args: {\n shell: {\n type: 'positional',\n description: `Shell flavor (${SUPPORTED.join(', ')}). Auto-detected from $SHELL if omitted.`,\n required: false\n },\n name: {\n type: 'string',\n description: 'Name of the generated shell function',\n default: 'fcd'\n }\n },\n async run({ args }) {\n const requested = (args.shell ?? detectShell()) as Shell;\n if (!SUPPORTED.includes(requested)) {\n consola.error(\n `Unsupported shell \"${requested}\". Supported: ${SUPPORTED.join(', ')}.`\n );\n process.exitCode = 1;\n return;\n }\n const fnName = args.name || 'fcd';\n const out = requested === 'fish' ? renderFish(fnName) : renderPosix(fnName);\n process.stdout.write(out);\n }\n});\n","import { defineCommand } from 'citty';\nimport { cloneCommand } from './commands/clone.ts';\nimport { configCommand } from './commands/config/index.ts';\nimport { pathCommand } from './commands/path.ts';\nimport { pickCommand } from './commands/pick.ts';\nimport { searchCommand } from './commands/search.ts';\nimport { shellInitCommand } from './commands/shell-init.ts';\n\nexport const rootCommand = defineCommand({\n meta: {\n name: 'forgemap',\n description:\n 'Manage a local repo layout of the form <root>/<forge.dir>/<owner>/<repo>'\n },\n subCommands: {\n clone: cloneCommand,\n path: pathCommand,\n search: searchCommand,\n pick: pickCommand,\n 'shell-init': shellInitCommand,\n config: configCommand\n }\n});\n","import { runMain } from 'citty';\nimport { rootCommand } from '../cli.ts';\n\nrunMain(rootCommand);\n"],"names":[],"mappings":";;;;;;;;;;;AAUA,MAAM,iBAAiC;AAAA,EACrC,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,IACN,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ;AAOA,eAAsB,mBACpB,UAAuB,IACA;AACvB,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,WAAW,QAAQ,cAAc;AACvC,QAAM,MAAM,WAAW,QAAQ,QAAQ,IAAK,QAAQ,OAAO,QAAQ,IAAA;AAEnE,QAAM,EAAE,QAAQ,WAAA,IAAe,MAAM,WAA+B;AAAA,IAClE,MAAM;AAAA,IACN;AAAA,IACA,YAAY,WAAW,WAAW;AAAA,IAClC,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,EAAA,CACX;AAED,QAAM,SAAyB;AAAA,IAC7B,MAAM,OAAO,QAAQ,eAAe;AAAA,IACpC,cAAc,OAAO,gBAAgB,eAAe;AAAA,IACpD,QAAQ;AAAA,MACN,GAAG,eAAe;AAAA,MAClB,GAAG,OAAO;AAAA,IAAA;AAAA,EACZ;AAGF,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,YAAY,cAAc;AAAA,IAC1B;AAAA,EAAA;AAEJ;ACpDO,SAAS,YACd,SACA,MACqB;AACrB,SAAO,IAAI,QAAQ,CAAC,gBAAgB,kBAAkB;AACpD,UAAM,QAAQ,MAAM,SAAS,MAAM,EAAE,OAAO,WAAW;AACvD,UAAM,GAAG,SAAS,aAAa;AAC/B,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,qBAAe,EAAE,MAAM,QAAQ,EAAA,CAAG;AAAA,IACpC,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,WAAW,SAAmC;AAC5D,SAAO,IAAI,QAAQ,CAAC,mBAAmB;AACrC,UAAM,QAAQ;AAAA,MACZ,QAAQ,aAAa,UAAU,UAAU;AAAA,MACzC,CAAC,OAAO;AAAA,MACR;AAAA,QACE,OAAO;AAAA,MAAA;AAAA,IACT;AAEF,UAAM,GAAG,SAAS,MAAM,eAAe,KAAK,CAAC;AAC7C,UAAM,GAAG,SAAS,CAAC,SAAS,eAAe,SAAS,CAAC,CAAC;AAAA,EACxD,CAAC;AACH;AC5BO,MAAM,gBAA8B;AAAA,EACzC,MAAM,MAAM,EAAE,OAAO,MAAM,QAAsB;AAC/C,QAAI,CAAE,MAAM,WAAW,IAAI,GAAI;AAC7B,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AACA,UAAM,EAAE,KAAA,IAAS,MAAM,YAAY,MAAM;AAAA,MACvC;AAAA,MACA;AAAA,MACA,GAAG,KAAK,IAAI,IAAI;AAAA,MAChB;AAAA,IAAA,CACD;AACD,QAAI,SAAS,GAAG;AACd,YAAM,IAAI,MAAM,kCAAkC,IAAI,EAAE;AAAA,IAC1D;AAAA,EACF;AACF;AChBO,SAAS,gBAAgB,MAA+B;AAC7D,UAAQ,MAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,YAAM,IAAI;AAAA,QACR,eAAe,IAAI;AAAA,MAAA;AAAA,IAEvB,SAAS;AACP,YAAM,aAAoB;AAC1B,YAAM,IAAI,MAAM,uBAAuB,OAAO,UAAU,CAAC,EAAE;AAAA,IAC7D;AAAA,EAAA;AAEJ;ACVA,MAAM,WAAW;AACjB,MAAM,WAAW;AACjB,MAAM,SAAS;AAEf,SAAS,eAAe,MAAsB;AAC5C,SAAO,KAAK,SAAS,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACrD;AAEO,SAAS,UAAU,OAA2B;AACnD,QAAM,UAAU,MAAM,KAAA;AACtB,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,eAAe;AAAA,EACjC;AAGA,QAAM,MAAM,OAAO,KAAK,OAAO;AAC/B,MAAI,KAAK;AACP,WAAO;AAAA,MACL,MAAM,IAAI,CAAC;AAAA,MACX,OAAO,IAAI,CAAC;AAAA,MACZ,MAAM,eAAe,IAAI,CAAC,CAAE;AAAA,IAAA;AAAA,EAEhC;AAGA,MAAI,eAAe,KAAK,OAAO,GAAG;AAChC,QAAI;AACJ,QAAI;AACF,YAAM,IAAI,IAAI,OAAO;AAAA,IACvB,QAAQ;AACN,YAAM,IAAI,MAAM,gBAAgB,OAAO,EAAE;AAAA,IAC3C;AACA,UAAM,WAAW,IAAI,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACvD,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,IAAI,MAAM,oCAAoC,OAAO,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,MACL,MAAM,IAAI;AAAA,MACV,OAAO,SAAS,CAAC;AAAA,MACjB,MAAM,eAAe,SAAS,CAAC,CAAE;AAAA,IAAA;AAAA,EAErC;AAGA,QAAM,QAAQ,SAAS,KAAK,OAAO;AACnC,MAAI,OAAO;AACT,WAAO;AAAA,MACL,WAAW,MAAM,CAAC;AAAA,MAClB,OAAO,MAAM,CAAC;AAAA,MACd,MAAM,eAAe,MAAM,CAAC,CAAE;AAAA,IAAA;AAAA,EAElC;AAGA,QAAM,QAAQ,SAAS,KAAK,OAAO;AACnC,MAAI,OAAO;AACT,WAAO;AAAA,MACL,OAAO,MAAM,CAAC;AAAA,MACd,MAAM,eAAe,MAAM,CAAC,CAAE;AAAA,IAAA;AAAA,EAElC;AAEA,QAAM,IAAI,MAAM,6BAA6B,KAAK,EAAE;AACtD;ACrEO,SAAS,YAAY,GAAmB;AAC7C,MAAI,MAAM,IAAK,QAAO,QAAA;AACtB,MAAI,EAAE,WAAW,IAAI,EAAG,QAAO,QAAQ,QAAA,GAAW,EAAE,MAAM,CAAC,CAAC;AAC5D,SAAO;AACT;AAEO,SAAS,YAAY,MAAc,WAA2B;AACnE,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,WAAW,QAAQ,EAAG,QAAO;AACjC,SAAO,QAAQ,WAAW,QAAQ;AACpC;ACKA,SAAS,gBACP,QACA,MACkD;AAClD,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,QAAI,MAAM,KAAK,YAAA,MAAkB,KAAK,eAAe;AACnD,aAAO,EAAE,MAAM,MAAA;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,YACd,QACA,SACc;AACd,QAAM,EAAE,QAAQ,UAAA,IAAc;AAE9B,MAAI;AACJ,MAAI;AAEJ,MAAI,OAAO,WAAW;AACpB,UAAM,YAAY,OAAO,OAAO,OAAO,SAAS;AAChD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,UAAU,OAAO,SAAS;AAAA,MAAA;AAAA,IAE9B;AACA,gBAAY,OAAO;AACnB,YAAQ;AAAA,EACV,WAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,gBAAgB,OAAO,QAAQ,OAAO,IAAI;AACxD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,iCAAiC,OAAO,IAAI;AAAA,MAAA;AAAA,IAEhD;AACA,gBAAY,MAAM;AAClB,YAAQ,MAAM;AAAA,EAChB,OAAO;AACL,UAAM,YAAY,OAAO,OAAO,OAAO,YAAY;AACnD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,kBAAkB,OAAO,YAAY;AAAA,MAAA;AAAA,IAEzC;AACA,gBAAY,OAAO;AACnB,YAAQ;AAAA,EACV;AAEA,QAAM,OAAO,YAAY,OAAO,MAAM,SAAS;AAC/C,QAAM,YAAY,KAAK,MAAM,MAAM,KAAK,OAAO,OAAO,OAAO,IAAI;AAEjE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,OAAO;AAAA,IACd,MAAM,OAAO;AAAA,IACb;AAAA,EAAA;AAEJ;ACpEO,MAAM,eAAe,cAAc;AAAA,EACxC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAAA,EAEf,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,MAAM,mBAAmB,EAAE,YAAY,KAAK,QAAQ;AACnE,UAAM,SAAS,UAAU,KAAK,IAAI;AAClC,UAAM,YAAY,OAAO,aACrB,QAAQ,OAAO,UAAU,IACzB,OAAO;AACX,UAAM,WAAW,YAAY,QAAQ;AAAA,MACnC,QAAQ,OAAO;AAAA,MACf;AAAA,IAAA,CACD;AAED,QAAI,WAAW,SAAS,SAAS,GAAG;AAClC,cAAQ,KAAK,qBAAqB,SAAS,SAAS,EAAE;AACtD;AAAA,IACF;AAEA,UAAM,MAAM,QAAQ,SAAS,SAAS,GAAG,EAAE,WAAW,MAAM;AAE5D,UAAM,UAAU,gBAAgB,SAAS,MAAM,IAAI;AACnD,UAAM,QAAQ,MAAM;AAAA,MAClB,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS;AAAA,MAChB,MAAM,SAAS;AAAA,MACf,MAAM,SAAS;AAAA,IAAA,CAChB;AAED,YAAQ;AAAA,MACN,UAAU,SAAS,KAAK,IAAI,SAAS,IAAI,MAAM,SAAS,SAAS;AAAA,IAAA;AAAA,EAErE;AACF,CAAC;ACnDD,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBV,MAAM,oBAAoB,cAAc;AAAA,EAC7C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EAAA;AAAA,EAEJ,MAAM;AAAA,IACJ,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,IAEX,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,QAAQ,QAAQ,IAAA,GAAO,KAAK,GAAG;AAC9C,UAAM,SAAS,KAAK,QAAQ,oBAAoB;AAEhD,UAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,WAAW,MAAM;AAEhD,QAAI;AACF,YAAM,UAAU,QAAQ,UAAU;AAAA,QAChC,UAAU;AAAA,QACV,MAAM,KAAK,QAAQ,MAAM;AAAA,MAAA,CAC1B;AAAA,IACH,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,UAAU;AACtD,gBAAQ,MAAM,GAAG,MAAM,4CAA4C;AACnE,gBAAQ,WAAW;AACnB;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAEA,YAAQ,QAAQ,SAAS,MAAM,EAAE;AAAA,EACnC;AACF,CAAC;AChEM,MAAM,oBAAoB,cAAc;AAAA,EAC7C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAAA,EAEf,MAAM;AAAA,IACJ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,MAAM,mBAAmB,EAAE,YAAY,KAAK,QAAQ;AACnE,YAAQ,OAAO;AAAA,MACb,KAAK;AAAA,QACH;AAAA,UACE,YAAY,OAAO,cAAc;AAAA,UACjC,KAAK,OAAO;AAAA,UACZ,QAAQ,OAAO;AAAA,QAAA;AAAA,QAEjB;AAAA,QACA;AAAA,MAAA,IACE;AAAA,IAAA;AAAA,EAER;AACF,CAAC;ACxBM,MAAM,gBAAgB,cAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAAA,EAEf,aAAa;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAEV,CAAC;ACPM,MAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAAA,EAEf,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,MAAM,mBAAmB,EAAE,YAAY,KAAK,QAAQ;AACnE,UAAM,SAAS,UAAU,KAAK,IAAI;AAClC,UAAM,YAAY,OAAO,aACrB,QAAQ,OAAO,UAAU,IACzB,OAAO;AACX,UAAM,WAAW,YAAY,QAAQ;AAAA,MACnC,QAAQ,OAAO;AAAA,MACf;AAAA,IAAA,CACD;AACD,YAAQ,OAAO,MAAM,GAAG,SAAS,SAAS;AAAA,CAAI;AAAA,EAChD;AACF,CAAC;ACnBD,eAAe,SAAS,MAAiC;AACvD,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,MAAM,EAAE,eAAe,MAAM;AAC3D,WAAO,QACJ,OAAO,CAAC,MAAM,EAAE,YAAA,KAAiB,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC,EACxD,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO,CAAA;AAC/D,UAAM;AAAA,EACR;AACF;AAOA,eAAsB,UAAU,SAA8C;AAC5E,QAAM,EAAE,QAAQ,UAAA,IAAc;AAC9B,QAAM,OAAO,YAAY,OAAO,MAAM,SAAS;AAC/C,QAAM,QAAuB,CAAA;AAE7B,aAAW,CAAC,WAAW,KAAK,KAAK,OAAO,QAAQ,OAAO,MAAM,GAAG;AAC9D,UAAM,YAAY,KAAK,MAAM,MAAM,GAAG;AACtC,UAAM,SAAS,MAAM,SAAS,SAAS;AACvC,eAAW,SAAS,QAAQ;AAC1B,YAAM,YAAY,KAAK,WAAW,KAAK;AACvC,YAAM,YAAY,MAAM,SAAS,SAAS;AAC1C,iBAAW,QAAQ,WAAW;AAC5B,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW,KAAK,WAAW,IAAI;AAAA,UAC/B,MAAM,GAAG,KAAK,IAAI,IAAI;AAAA,QAAA,CACvB;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;ACjDO,MAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EAAA;AAAA,EAEJ,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,MAAM,mBAAmB,EAAE,YAAY,KAAK,QAAQ;AACnE,UAAM,YAAY,OAAO,aACrB,QAAQ,OAAO,UAAU,IACzB,OAAO;AACX,UAAM,MAAM,MAAM,UAAU,EAAE,QAAQ,OAAO,QAAQ,WAAW;AAEhE,QAAI;AACJ,QAAI,KAAK,OAAO;AACd,YAAM,OAAO,IAAI,KAAK,KAAK;AAAA,QACzB,MAAM,CAAC,QAAQ,SAAS,MAAM;AAAA,QAC9B,WAAW;AAAA,QACX,gBAAgB;AAAA,MAAA,CACjB;AACD,mBAAa,KAAK,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IACxD,OAAO;AACL,mBAAa;AAAA,IACf;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,cAAQ;AAAA,QACN,KAAK,QACD,mBAAmB,KAAK,KAAK,OAC7B;AAAA,MAAA;AAEN,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,cAAQ,OAAO,MAAM,GAAG,WAAW,CAAC,EAAG,SAAS;AAAA,CAAI;AACpD;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,cAAQ;AAAA,QACN;AAAA,MAAA;AAEF,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,QAAQ,OAAO,iBAAiB;AAAA,MACnD,MAAM;AAAA,MACN,SAAS,WAAW,IAAI,CAAC,OAAO;AAAA,QAC9B,OAAO,GAAG,OAAO,KAAK,GAAG,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,IAAI;AAAA,QACjD,OAAO,EAAE;AAAA,QACT,MAAM,EAAE;AAAA,MAAA,EACR;AAAA,IAAA,CACH;AAED,QAAI,OAAO,WAAW,YAAY,QAAQ;AACxC,cAAQ,OAAO,MAAM,GAAG,MAAM;AAAA,CAAI;AAAA,IACpC;AAAA,EACF;AACF,CAAC;ACjEM,SAAS,UAAU,cAA8B;AACtD,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,QAAQ;AACV,WAAO,iBAAiB,MAAM,GAAG,YAAY;AAAA,EAC/C;AACA,SAAO,UAAU,YAAY;AAC/B;ACLA,SAAS,KAAK,KAAa,MAAsB;AAC/C,SAAO,WAAW,GAAG,OAAO,IAAI;AAClC;AAEA,SAAS,WAAW,OAA8B;AAChD,QAAM,6BAAa,IAAA;AACnB,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,OAAO,IAAI,EAAE,SAAS;AACnC,QAAI,KAAM,MAAK,KAAK,CAAC;AAAA,gBACT,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,OAAO;AAAA,MACtC,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,UAAU,MAAM,IAAI,CAAC,OAAO;AAAA,QAC1B,MAAM,GAAG,OAAO,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,UAAU,EAAE,SAAS,GAAG,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC;AAAA,MAAA,EACtF;AAAA,IAAA,EACF;AAAA,EAAA;AAEN;AAEO,MAAM,gBAAgB,cAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EAAA;AAAA,EAEJ,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA,IAEZ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,MACF,SAAS;AAAA,IAAA;AAAA,IAEX,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,IAEf,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,SAAS,MAAM,mBAAmB,EAAE,YAAY,KAAK,QAAQ;AACnE,UAAM,YAAY,OAAO,aACrB,QAAQ,OAAO,UAAU,IACzB,OAAO;AACX,UAAM,QAAQ,MAAM,UAAU,EAAE,QAAQ,OAAO,QAAQ,WAAW;AAElE,UAAM,OAAO,IAAI,KAAK,OAAO;AAAA,MAC3B,MAAM,CAAC,QAAQ,SAAS,MAAM;AAAA,MAC9B,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAAA,CACf;AAED,UAAM,QAAQ,KAAK,QAAQ,OAAO,SAAS,KAAK,OAAO,EAAE,IAAI;AAC7D,UAAM,UAAU,KAAK,OAAO,KAAK,OAAO,QAAQ,EAAE,MAAA,IAAU,MAAS;AACrE,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AAEvC,UAAM,UAAoB,CAAC,QAAQ,UAAU,QAAQ,MAAM;AAC3D,QAAI,CAAC,QAAQ,SAAS,KAAK,MAAgB,GAAG;AAC5C,cAAQ;AAAA,QACN,2BAA2B,KAAK,MAAM,eAAe,QAAQ,KAAK,IAAI,CAAC;AAAA,MAAA;AAEzE,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM,YAAY,KAAK;AACvB,UAAM,SACJ,cAAc,SACV,QAAQ,OAAO,QACb,WACA,SACF;AAEN,QAAI,MAAM,WAAW,GAAG;AACtB,UAAI,WAAW,SAAU,SAAQ,KAAK,mBAAmB,KAAK,KAAK,IAAI;AACvE;AAAA,IACF;AAEA,QAAI,WAAW,UAAU;AACvB,cAAQ,OAAO,MAAM,GAAG,WAAW,KAAK,CAAC;AAAA,CAAI;AAC7C;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO;AACxB,cAAQ,OAAO;AAAA,QACb,GAAG,WAAW,SAAS,KAAK,OAAO,KAAK,SAAS;AAAA;AAAA,MAAA;AAAA,IAErD;AAAA,EACF;AACF,CAAC;AC9GD,MAAM,YAAqB,CAAC,OAAO,QAAQ,MAAM;AAEjD,SAAS,cAAqB;AAC5B,QAAM,MAAM,QAAQ,IAAI,SAAS;AACjC,MAAI,IAAI,SAAS,OAAO,EAAG,QAAO;AAClC,MAAI,IAAI,SAAS,OAAO,EAAG,QAAO;AAClC,SAAO;AACT;AAEA,SAAS,YAAY,QAAwB;AAC3C,SAAO;AAAA;AAAA;AAAA,EAGP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBR;AAEA,SAAS,WAAW,QAAwB;AAC1C,SAAO;AAAA;AAAA;AAAA,WAGE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBjB;AAEO,MAAM,mBAAmB,cAAc;AAAA,EAC5C,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EAAA;AAAA,EAEJ,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa,iBAAiB,UAAU,KAAK,IAAI,CAAC;AAAA,MAClD,UAAU;AAAA,IAAA;AAAA,IAEZ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,MAAM,IAAI,EAAE,QAAQ;AAClB,UAAM,YAAa,KAAK,SAAS,YAAA;AACjC,QAAI,CAAC,UAAU,SAAS,SAAS,GAAG;AAClC,cAAQ;AAAA,QACN,sBAAsB,SAAS,iBAAiB,UAAU,KAAK,IAAI,CAAC;AAAA,MAAA;AAEtE,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM,SAAS,KAAK,QAAQ;AAC5B,UAAM,MAAM,cAAc,SAAS,WAAW,MAAM,IAAI,YAAY,MAAM;AAC1E,YAAQ,OAAO,MAAM,GAAG;AAAA,EAC1B;AACF,CAAC;ACjGM,MAAM,cAAc,cAAc;AAAA,EACvC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EAAA;AAAA,EAEJ,aAAa;AAAA,IACX,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,cAAc;AAAA,IACd,QAAQ;AAAA,EAAA;AAEZ,CAAC;ACnBD,QAAQ,WAAW;"}
1
+ {"version":3,"file":"forgemap.mjs","sources":["../../src/commands/cd.ts","../../src/config/load.ts","../../src/utils/exec.ts","../../src/forges/github.ts","../../src/forges/registry.ts","../../src/slug/parse.ts","../../src/utils/path.ts","../../src/slug/resolve.ts","../../src/commands/clone.ts","../../src/commands/config/init.ts","../../src/commands/config/show.ts","../../src/commands/config/index.ts","../../src/commands/open.ts","../../src/commands/path.ts","../../src/repos/scan.ts","../../src/commands/pick.ts","../../src/commands/search.ts","../../src/commands/shell-init.ts","../../src/cli.ts","../../src/bin/forgemap.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport consola from 'consola';\n\n/**\n * When the shell wrapper from `forgemap shell-init` is sourced, it\n * intercepts `forgemap cd <slug>` before the binary is called and runs\n * the actual `cd` in the user's shell. If the binary itself ever runs\n * this command, the wrapper isn't active — we print a hint so the user\n * knows how to enable it.\n */\nexport const cdCommand = defineCommand({\n meta: {\n name: 'cd',\n description: 'Change directory into a repo (requires shell integration)'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, full URL, or fuzzy query',\n required: false\n }\n },\n async run() {\n consola.error(\n 'forgemap cd needs shell integration to actually change directory.'\n );\n consola.info('Source the wrapper once and try again:');\n consola.info(' eval \"$(forgemap shell-init)\" # zsh/bash');\n consola.info(' forgemap shell-init fish | source # fish');\n consola.info(\n 'Or, if you just want the path on stdout, use: forgemap path <slug>'\n );\n process.exitCode = 1;\n }\n});\n","import { loadConfig } from 'c12';\nimport { dirname } from 'pathe';\nimport type { ForgeMapConfig, ForgeMapUserConfig } from './schema.ts';\n\nexport interface LoadedConfig {\n config: ForgeMapConfig;\n configFile: string | undefined;\n cwd: string;\n}\n\nconst DEFAULT_CONFIG: ForgeMapConfig = {\n root: '.',\n defaultForge: 'github',\n forges: {\n github: {\n type: 'github',\n host: 'github.com',\n dir: 'comGithub'\n }\n }\n};\n\nexport interface LoadOptions {\n cwd?: string;\n configFile?: string;\n}\n\nexport async function loadForgeMapConfig(\n options: LoadOptions = {}\n): Promise<LoadedConfig> {\n const envConfig = process.env.FORGEMAP_CONFIG;\n const explicit = options.configFile ?? envConfig;\n const cwd = explicit ? dirname(explicit) : (options.cwd ?? process.cwd());\n\n const { config, configFile } = await loadConfig<ForgeMapUserConfig>({\n name: 'forgemap',\n cwd,\n configFile: explicit ? explicit : 'forgemap.config',\n rcFile: false,\n globalRc: false,\n dotenv: false,\n defaults: DEFAULT_CONFIG\n });\n\n const merged: ForgeMapConfig = {\n root: config.root ?? DEFAULT_CONFIG.root,\n defaultForge: config.defaultForge ?? DEFAULT_CONFIG.defaultForge,\n forges: {\n ...DEFAULT_CONFIG.forges,\n ...config.forges\n }\n };\n\n return {\n config: merged,\n configFile: configFile || undefined,\n cwd\n };\n}\n","import { spawn } from 'node:child_process';\n\nexport interface ExecResult {\n code: number;\n}\n\nexport function execInherit(\n command: string,\n args: string[]\n): Promise<ExecResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(command, args, { stdio: 'inherit' });\n child.on('error', rejectPromise);\n child.on('close', (code) => {\n resolvePromise({ code: code ?? 0 });\n });\n });\n}\n\nexport function hasCommand(command: string): Promise<boolean> {\n return new Promise((resolvePromise) => {\n const child = spawn(\n process.platform === 'win32' ? 'where' : 'which',\n [command],\n {\n stdio: 'ignore'\n }\n );\n child.on('error', () => resolvePromise(false));\n child.on('close', (code) => resolvePromise(code === 0));\n });\n}\n","import { execInherit, hasCommand } from '../utils/exec.ts';\nimport type { CloneOptions, ForgeAdapter } from './types.ts';\n\nexport const githubAdapter: ForgeAdapter = {\n async clone({ owner, repo, dest }: CloneOptions) {\n if (!(await hasCommand('gh'))) {\n throw new Error(\n 'GitHub CLI (`gh`) is not installed. Install it from https://cli.github.com/ and run `gh auth login`.'\n );\n }\n const { code } = await execInherit('gh', [\n 'repo',\n 'clone',\n `${owner}/${repo}`,\n dest\n ]);\n if (code !== 0) {\n throw new Error(`gh repo clone exited with code ${code}`);\n }\n }\n};\n","import type { ForgeType } from '../config/schema.ts';\nimport { githubAdapter } from './github.ts';\nimport type { ForgeAdapter } from './types.ts';\n\nexport function getForgeAdapter(type: ForgeType): ForgeAdapter {\n switch (type) {\n case 'github':\n return githubAdapter;\n case 'gitlab':\n case 'gitea':\n case 'codeberg':\n throw new Error(\n `Forge type \"${type}\" is not implemented yet. Only \"github\" is supported in this release.`\n );\n default: {\n const exhaustive: never = type;\n throw new Error(`Unknown forge type: ${String(exhaustive)}`);\n }\n }\n}\n","export interface ParsedSlug {\n /** Forge alias if explicitly specified via `<forge>:<owner>/<repo>` */\n forgeName?: string;\n /** Host if extracted from URL/SSH form */\n host?: string;\n owner: string;\n repo: string;\n}\n\nconst SHORT_RE = /^([\\w.-]+)\\/([\\w.-]+)$/;\nconst NAMED_RE = /^([\\w.-]+):([\\w.-]+)\\/([\\w.-]+)$/;\nconst SSH_RE = /^git@([\\w.-]+):([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?$/;\n\nfunction stripGitSuffix(repo: string): string {\n return repo.endsWith('.git') ? repo.slice(0, -4) : repo;\n}\n\nexport function parseSlug(input: string): ParsedSlug {\n const trimmed = input.trim();\n if (!trimmed) {\n throw new Error('Slug is empty');\n }\n\n // git@host:owner/repo(.git)\n const ssh = SSH_RE.exec(trimmed);\n if (ssh) {\n return {\n host: ssh[1],\n owner: ssh[2]!,\n repo: stripGitSuffix(ssh[3]!)\n };\n }\n\n // https://host/owner/repo(.git) or http://...\n if (/^https?:\\/\\//.test(trimmed)) {\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n throw new Error(`Invalid URL: ${trimmed}`);\n }\n const segments = url.pathname.split('/').filter(Boolean);\n if (segments.length < 2) {\n throw new Error(`URL must contain owner and repo: ${trimmed}`);\n }\n return {\n host: url.host,\n owner: segments[0]!,\n repo: stripGitSuffix(segments[1]!)\n };\n }\n\n // forge:owner/repo\n const named = NAMED_RE.exec(trimmed);\n if (named) {\n return {\n forgeName: named[1],\n owner: named[2]!,\n repo: stripGitSuffix(named[3]!)\n };\n }\n\n // owner/repo\n const short = SHORT_RE.exec(trimmed);\n if (short) {\n return {\n owner: short[1]!,\n repo: stripGitSuffix(short[2]!)\n };\n }\n\n throw new Error(`Unrecognized slug format: ${input}`);\n}\n","import { homedir } from 'node:os';\nimport { isAbsolute, resolve } from 'pathe';\n\nexport function expandTilde(p: string): string {\n if (p === '~') return homedir();\n if (p.startsWith('~/')) return resolve(homedir(), p.slice(2));\n return p;\n}\n\nexport function resolveRoot(root: string, configDir: string): string {\n const expanded = expandTilde(root);\n if (isAbsolute(expanded)) return expanded;\n return resolve(configDir, expanded);\n}\n","import { join } from 'pathe';\nimport type { ForgeConfig, ForgeMapConfig } from '../config/schema.ts';\nimport { resolveRoot } from '../utils/path.ts';\nimport type { ParsedSlug } from './parse.ts';\n\nexport interface ResolvedSlug {\n forgeName: string;\n forge: ForgeConfig;\n owner: string;\n repo: string;\n localPath: string;\n}\n\nexport interface ResolveOptions {\n config: ForgeMapConfig;\n configDir: string;\n}\n\nfunction findForgeByHost(\n forges: ForgeMapConfig['forges'],\n host: string\n): { name: string; forge: ForgeConfig } | undefined {\n for (const [name, forge] of Object.entries(forges)) {\n if (forge.host.toLowerCase() === host.toLowerCase()) {\n return { name, forge };\n }\n }\n return undefined;\n}\n\nexport function resolveSlug(\n parsed: ParsedSlug,\n options: ResolveOptions\n): ResolvedSlug {\n const { config, configDir } = options;\n\n let forgeName: string;\n let forge: ForgeConfig;\n\n if (parsed.forgeName) {\n const candidate = config.forges[parsed.forgeName];\n if (!candidate) {\n throw new Error(\n `Forge \"${parsed.forgeName}\" is not defined in forgemap.config`\n );\n }\n forgeName = parsed.forgeName;\n forge = candidate;\n } else if (parsed.host) {\n const match = findForgeByHost(config.forges, parsed.host);\n if (!match) {\n throw new Error(\n `No forge configured for host \"${parsed.host}\". Add it to forgemap.config.ts.`\n );\n }\n forgeName = match.name;\n forge = match.forge;\n } else {\n const candidate = config.forges[config.defaultForge];\n if (!candidate) {\n throw new Error(\n `Default forge \"${config.defaultForge}\" is not defined in forgemap.config`\n );\n }\n forgeName = config.defaultForge;\n forge = candidate;\n }\n\n const root = resolveRoot(config.root, configDir);\n const localPath = join(root, forge.dir, parsed.owner, parsed.repo);\n\n return {\n forgeName,\n forge,\n owner: parsed.owner,\n repo: parsed.repo,\n localPath\n };\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { getForgeAdapter } from '../forges/registry.ts';\nimport { parseSlug } from '../slug/parse.ts';\nimport { resolveSlug } from '../slug/resolve.ts';\n\nexport const cloneCommand = defineCommand({\n meta: {\n name: 'clone',\n description: 'Clone a repo into the configured local layout'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, or full URL',\n required: true\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const parsed = parseSlug(args.slug);\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const resolved = resolveSlug(parsed, {\n config: loaded.config,\n configDir\n });\n\n if (existsSync(resolved.localPath)) {\n consola.info(`Already cloned at ${resolved.localPath}`);\n return;\n }\n\n await mkdir(dirname(resolved.localPath), { recursive: true });\n\n const adapter = getForgeAdapter(resolved.forge.type);\n await adapter.clone({\n forge: resolved.forge,\n owner: resolved.owner,\n repo: resolved.repo,\n dest: resolved.localPath\n });\n\n consola.success(\n `Cloned ${resolved.owner}/${resolved.repo} → ${resolved.localPath}`\n );\n }\n});\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { dirname, join, resolve } from 'pathe';\n\nconst TEMPLATE = `/**\n * forgemap configuration.\n *\n * For type-safe authoring, install forgemap and switch to:\n * import { defineForgeMapConfig } from 'forgemap/config';\n * export default defineForgeMapConfig({ ... });\n *\n * @type {import('forgemap').ForgeMapUserConfig}\n */\nexport default {\n root: '.',\n defaultForge: 'github',\n forges: {\n github: {\n type: 'github',\n host: 'github.com',\n dir: 'comGithub'\n }\n }\n};\n`;\n\nexport const configInitCommand = defineCommand({\n meta: {\n name: 'init',\n description:\n 'Create a forgemap.config.ts in the current (or given) directory'\n },\n args: {\n out: {\n type: 'string',\n description: 'Directory to write forgemap.config.ts into',\n default: '.'\n },\n force: {\n type: 'boolean',\n description: 'Overwrite if forgemap.config.ts already exists',\n default: false\n }\n },\n async run({ args }) {\n const outDir = resolve(process.cwd(), args.out);\n const target = join(outDir, 'forgemap.config.ts');\n\n await mkdir(dirname(target), { recursive: true });\n\n try {\n await writeFile(target, TEMPLATE, {\n encoding: 'utf8',\n flag: args.force ? 'w' : 'wx'\n });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n consola.error(`${target} already exists. Use --force to overwrite.`);\n process.exitCode = 1;\n return;\n }\n throw error;\n }\n\n consola.success(`Wrote ${target}`);\n }\n});\n","import { defineCommand } from 'citty';\nimport { loadForgeMapConfig } from '../../config/load.ts';\n\nexport const configShowCommand = defineCommand({\n meta: {\n name: 'show',\n description: 'Print the resolved forgemap config and its source path'\n },\n args: {\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n process.stdout.write(\n JSON.stringify(\n {\n configFile: loaded.configFile ?? null,\n cwd: loaded.cwd,\n config: loaded.config\n },\n null,\n 2\n ) + '\\n'\n );\n }\n});\n","import { defineCommand } from 'citty';\nimport { configInitCommand } from './init.ts';\nimport { configShowCommand } from './show.ts';\n\nexport const configCommand = defineCommand({\n meta: {\n name: 'config',\n description: 'Manage the forgemap config file'\n },\n subCommands: {\n init: configInitCommand,\n show: configShowCommand\n }\n});\n","import { spawn } from 'node:child_process';\nimport { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { parseSlug } from '../slug/parse.ts';\nimport { resolveSlug } from '../slug/resolve.ts';\n\ninterface OpenInvocation {\n cmd: string;\n args: string[];\n}\n\nfunction platformOpen(localPath: string): OpenInvocation {\n const distro = process.env.WSL_DISTRO_NAME;\n if (distro) {\n const winPath = `\\\\\\\\wsl$\\\\${distro}${localPath.replaceAll('/', '\\\\')}`;\n return { cmd: 'explorer.exe', args: [winPath] };\n }\n if (process.platform === 'darwin') {\n return { cmd: 'open', args: [localPath] };\n }\n return { cmd: 'xdg-open', args: [localPath] };\n}\n\nexport const openCommand = defineCommand({\n meta: {\n name: 'open',\n description:\n 'Open a repo in the OS file manager (Explorer on WSL, Finder on macOS, xdg-open elsewhere)'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, or full URL',\n required: true\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const parsed = parseSlug(args.slug);\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const resolved = resolveSlug(parsed, {\n config: loaded.config,\n configDir\n });\n\n const { cmd, args: cmdArgs } = platformOpen(resolved.localPath);\n consola.info(`Opening ${resolved.localPath}`);\n\n const child = spawn(cmd, cmdArgs, {\n stdio: 'ignore',\n detached: true\n });\n child.on('error', (error: NodeJS.ErrnoException) => {\n if (error.code === 'ENOENT') {\n consola.error(\n `Could not find \\`${cmd}\\`. Install it (or open the path manually).`\n );\n process.exitCode = 1;\n } else {\n consola.error(error.message);\n process.exitCode = 1;\n }\n });\n child.unref();\n }\n});\n","import { defineCommand } from 'citty';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { dirname } from 'pathe';\nimport { parseSlug } from '../slug/parse.ts';\nimport { resolveSlug } from '../slug/resolve.ts';\n\nexport const pathCommand = defineCommand({\n meta: {\n name: 'path',\n description: 'Print the local path where a repo lives (or would live)'\n },\n args: {\n slug: {\n type: 'positional',\n description: 'owner/repo, forge:owner/repo, or full URL',\n required: true\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const parsed = parseSlug(args.slug);\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const resolved = resolveSlug(parsed, {\n config: loaded.config,\n configDir\n });\n process.stdout.write(`${resolved.localPath}\\n`);\n }\n});\n","import { readdir } from 'node:fs/promises';\nimport { join } from 'pathe';\nimport type { ForgeConfig, ForgeMapConfig } from '../config/schema.ts';\nimport { resolveRoot } from '../utils/path.ts';\n\nexport interface ScannedRepo {\n forgeName: string;\n forge: ForgeConfig;\n owner: string;\n repo: string;\n localPath: string;\n /** Convenience: `<owner>/<repo>` */\n slug: string;\n}\n\nasync function listDirs(path: string): Promise<string[]> {\n try {\n const entries = await readdir(path, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => e.name);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw error;\n }\n}\n\nexport interface ScanOptions {\n config: ForgeMapConfig;\n configDir: string;\n}\n\nexport async function scanRepos(options: ScanOptions): Promise<ScannedRepo[]> {\n const { config, configDir } = options;\n const root = resolveRoot(config.root, configDir);\n const repos: ScannedRepo[] = [];\n\n for (const [forgeName, forge] of Object.entries(config.forges)) {\n const forgeRoot = join(root, forge.dir);\n const owners = await listDirs(forgeRoot);\n for (const owner of owners) {\n const ownerPath = join(forgeRoot, owner);\n const repoNames = await listDirs(ownerPath);\n for (const repo of repoNames) {\n repos.push({\n forgeName,\n forge,\n owner,\n repo,\n localPath: join(ownerPath, repo),\n slug: `${owner}/${repo}`\n });\n }\n }\n }\n\n return repos;\n}\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { colors } from 'consola/utils';\nimport Fuse from 'fuse.js';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { type ScannedRepo, scanRepos } from '../repos/scan.ts';\n\nexport const pickCommand = defineCommand({\n meta: {\n name: 'pick',\n description:\n 'Interactively pick a cloned repo from the configured layout and print its path'\n },\n args: {\n query: {\n type: 'positional',\n description: 'Optional fuzzy filter applied before showing the picker',\n required: false\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const all = await scanRepos({ config: loaded.config, configDir });\n\n let candidates: ScannedRepo[];\n if (args.query) {\n const fuse = new Fuse(all, {\n keys: ['slug', 'owner', 'repo'],\n threshold: 0.3,\n ignoreLocation: true\n });\n candidates = fuse.search(args.query).map((r) => r.item);\n } else {\n candidates = all;\n }\n\n if (candidates.length === 0) {\n consola.error(\n args.query\n ? `No repos match \"${args.query}\".`\n : 'No repos found under the configured root.'\n );\n process.exitCode = 1;\n return;\n }\n\n if (candidates.length === 1) {\n process.stdout.write(`${candidates[0]!.localPath}\\n`);\n return;\n }\n\n if (!process.stdin.isTTY) {\n consola.error(\n 'pick requires an interactive terminal. Use `forgemap search` for non-interactive output.'\n );\n process.exitCode = 1;\n return;\n }\n\n const choice = await consola.prompt('Select a repo', {\n type: 'select',\n options: candidates.map((r) => ({\n label: `${colors.gray(`${r.forgeName}:`)}${r.slug}`,\n value: r.localPath,\n hint: r.localPath\n }))\n });\n\n if (typeof choice === 'string' && choice) {\n process.stdout.write(`${choice}\\n`);\n }\n }\n});\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\nimport { colors, formatTree } from 'consola/utils';\nimport Fuse from 'fuse.js';\nimport { dirname } from 'pathe';\nimport { loadForgeMapConfig } from '../config/load.ts';\nimport { type ScannedRepo, scanRepos } from '../repos/scan.ts';\n\ntype Format = 'auto' | 'pretty' | 'path' | 'slug';\n\nfunction renderTree(repos: ScannedRepo[]): string {\n const groups = new Map<string, ScannedRepo[]>();\n for (const r of repos) {\n const list = groups.get(r.forgeName);\n if (list) list.push(r);\n else groups.set(r.forgeName, [r]);\n }\n\n return formatTree(\n Array.from(groups, ([forge, items]) => ({\n text: colors.bold(forge),\n children: items.map((r) => ({\n text: `${colors.cyan(r.slug)} ${colors.dim(r.localPath)}`\n }))\n }))\n );\n}\n\nexport const searchCommand = defineCommand({\n meta: {\n name: 'search',\n description:\n 'Fuzzy-search cloned repos by owner/repo and print matching repos'\n },\n args: {\n query: {\n type: 'positional',\n description: 'Search term (matched fuzzily against <owner>/<repo>)',\n required: true\n },\n format: {\n type: 'string',\n description:\n 'Output format: auto (default), pretty, path, or slug. auto picks pretty in a TTY, path when piped.',\n default: 'auto'\n },\n limit: {\n type: 'string',\n description: 'Maximum number of matches to print (default: unlimited)'\n },\n config: {\n type: 'string',\n description: 'Path to forgemap.config.ts (overrides walk-up discovery)'\n }\n },\n async run({ args }) {\n const loaded = await loadForgeMapConfig({ configFile: args.config });\n const configDir = loaded.configFile\n ? dirname(loaded.configFile)\n : loaded.cwd;\n const repos = await scanRepos({ config: loaded.config, configDir });\n\n const fuse = new Fuse(repos, {\n keys: ['slug', 'owner', 'repo'],\n threshold: 0.3,\n ignoreLocation: true,\n includeScore: true\n });\n\n const limit = args.limit ? Number.parseInt(args.limit, 10) : undefined;\n const results = fuse.search(args.query, limit ? { limit } : undefined);\n const items = results.map((r) => r.item);\n\n const allowed: Format[] = ['auto', 'pretty', 'path', 'slug'];\n if (!allowed.includes(args.format as Format)) {\n consola.error(\n `Invalid --format value \"${args.format}\". Allowed: ${allowed.join(', ')}.`\n );\n process.exitCode = 1;\n return;\n }\n const requested = args.format as Format;\n const format: Exclude<Format, 'auto'> =\n requested === 'auto'\n ? process.stdout.isTTY\n ? 'pretty'\n : 'path'\n : requested;\n\n if (items.length === 0) {\n if (format === 'pretty') consola.info(`No matches for \"${args.query}\".`);\n return;\n }\n\n if (format === 'pretty') {\n process.stdout.write(`${renderTree(items)}\\n`);\n return;\n }\n\n for (const item of items) {\n process.stdout.write(\n `${format === 'slug' ? item.slug : item.localPath}\\n`\n );\n }\n }\n});\n","import { defineCommand } from 'citty';\nimport consola from 'consola';\n\ntype Shell = 'zsh' | 'bash' | 'fish';\n\nconst SUPPORTED: Shell[] = ['zsh', 'bash', 'fish'];\n\nfunction detectShell(): Shell {\n const env = process.env.SHELL ?? '';\n if (env.endsWith('/fish')) return 'fish';\n if (env.endsWith('/bash')) return 'bash';\n return 'zsh';\n}\n\nfunction renderPosix(name: string): string {\n return `# forgemap shell integration — drop into your ~/.zshrc / ~/.bashrc:\n# eval \"$(forgemap shell-init)\"\n#\n# Wraps the forgemap binary so that \\`${name} cd <slug>\\` actually changes\n# directory in this shell. All other subcommands fall through unchanged.\n\n${name}() {\n if [ \"$1\" = \"cd\" ]; then\n shift\n local target\n if [ \"$#\" -eq 0 ]; then\n target=$(command forgemap pick) || return $?\n else\n local matches\n matches=$(command forgemap search \"$1\" --format path)\n local count\n count=$(printf '%s' \"$matches\" | grep -c '^/' || true)\n if [ \"$count\" = \"1\" ]; then\n target=\"$matches\"\n elif [ \"$count\" = \"0\" ]; then\n echo \"forgemap cd: no match for $1\" >&2\n return 1\n else\n target=$(command forgemap pick \"$1\") || return $?\n fi\n fi\n [ -n \"$target\" ] && builtin cd \"$target\"\n return\n fi\n command forgemap \"$@\"\n}\n`;\n}\n\nfunction renderFish(name: string): string {\n return `# forgemap shell integration — drop into your ~/.config/fish/config.fish:\n# forgemap shell-init fish | source\n\nfunction ${name} --description \"forgemap with cd interception\"\n if test (count $argv) -ge 1 -a \"$argv[1]\" = \"cd\"\n set --erase argv[1]\n set target \"\"\n if test (count $argv) -eq 0\n set target (command forgemap pick); or return $status\n else\n set matches (command forgemap search $argv[1] --format path)\n set count (count $matches)\n if test $count -eq 1\n set target $matches[1]\n else if test $count -eq 0\n echo \"forgemap cd: no match for $argv[1]\" >&2\n return 1\n else\n set target (command forgemap pick $argv[1]); or return $status\n end\n end\n test -n \"$target\"; and builtin cd $target\n return\n end\n command forgemap $argv\nend\n`;\n}\n\nexport const shellInitCommand = defineCommand({\n meta: {\n name: 'shell-init',\n description:\n 'Print a shell wrapper that adds `forgemap cd <slug>` as a real cd. Source it via `eval \"$(forgemap shell-init)\"`.'\n },\n args: {\n shell: {\n type: 'positional',\n description: `Shell flavor (${SUPPORTED.join(', ')}). Auto-detected from $SHELL if omitted.`,\n required: false\n },\n name: {\n type: 'string',\n description: 'Name of the generated wrapper function (default: forgemap)',\n default: 'forgemap'\n }\n },\n async run({ args }) {\n const requested = (args.shell ?? detectShell()) as Shell;\n if (!SUPPORTED.includes(requested)) {\n consola.error(\n `Unsupported shell \"${requested}\". Supported: ${SUPPORTED.join(', ')}.`\n );\n process.exitCode = 1;\n return;\n }\n const name = args.name || 'forgemap';\n const out = requested === 'fish' ? renderFish(name) : renderPosix(name);\n process.stdout.write(out);\n }\n});\n","import { defineCommand } from 'citty';\nimport { cdCommand } from './commands/cd.ts';\nimport { cloneCommand } from './commands/clone.ts';\nimport { configCommand } from './commands/config/index.ts';\nimport { openCommand } from './commands/open.ts';\nimport { pathCommand } from './commands/path.ts';\nimport { pickCommand } from './commands/pick.ts';\nimport { searchCommand } from './commands/search.ts';\nimport { shellInitCommand } from './commands/shell-init.ts';\n\nexport const rootCommand = defineCommand({\n meta: {\n name: 'forgemap',\n description:\n 'Manage a local repo layout of the form <root>/<forge.dir>/<owner>/<repo>'\n },\n subCommands: {\n clone: cloneCommand,\n cd: cdCommand,\n path: pathCommand,\n open: openCommand,\n search: searchCommand,\n pick: pickCommand,\n 'shell-init': shellInitCommand,\n config: configCommand\n }\n});\n","import { runMain } from 'citty';\nimport { rootCommand } from '../cli.ts';\n\nrunMain(rootCommand);\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "forgemap",
4
- "version": "0.1.0-dev.19-201b895",
4
+ "version": "0.1.0-dev.21-66ff114",
5
5
  "description": "CLI that manages a local repo layout grouped by git server, organization and repository name.",
6
6
  "keywords": [
7
7
  "cli",