forgemap 0.1.0-dev.20-4352c3f → 0.1.0-dev.22-d31fc67

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
@@ -42,6 +42,9 @@ pnpm add -g forgemap
42
42
  > [!IMPORTANT]
43
43
  > `forgemap clone` shells out to the [GitHub CLI](https://cli.github.com/) (`gh`). Install it once and run `gh auth login` so cloning works against private repos.
44
44
 
45
+ > [!TIP]
46
+ > Hacking on forgemap itself? See [CONTRIBUTING.md → Trying the CLI locally](CONTRIBUTING.md#trying-the-cli-locally) — covers `pnpm setup`, `pnpm link --global .` and the shell-wrapper source.
47
+
45
48
  ## 🚀 Quick start
46
49
 
47
50
  ```bash
@@ -67,7 +70,7 @@ fcd kirchDev/laravel-pbac
67
70
 
68
71
  ### Real `cd` via shell integration (recommended)
69
72
 
70
- Source the shell function once:
73
+ Source the shell wrapper once:
71
74
 
72
75
  ```bash
73
76
  # zsh/bash — drop into ~/.zshrc or ~/.bashrc
@@ -77,14 +80,16 @@ eval "$(forgemap shell-init)"
77
80
  forgemap shell-init fish | source
78
81
  ```
79
82
 
80
- That defines `fcd`:
83
+ After that, `forgemap cd <slug>` actually changes directory:
81
84
 
82
85
  ```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
86
+ forgemap cd laravel # cd straight into kirchDev/laravel-pbac (single match)
87
+ forgemap cd kirch # multiple matches → interactive picker
88
+ forgemap cd # no arg → picker over every cloned repo
86
89
  ```
87
90
 
91
+ All other `forgemap` subcommands pass through to the real binary unchanged.
92
+
88
93
  ### Search and pick on demand
89
94
 
90
95
  ```bash
@@ -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",
@@ -619,68 +644,73 @@ function detectShell() {
619
644
  if (env.endsWith("/bash")) return "bash";
620
645
  return "zsh";
621
646
  }
622
- function renderPosix(fnName) {
647
+ function renderPosix(name) {
623
648
  return `# forgemap shell integration — drop into your ~/.zshrc / ~/.bashrc:
624
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.
625
653
 
626
- ${fnName}() {
627
- if [ "$#" -eq 0 ]; then
654
+ ${name}() {
655
+ if [ "$1" = "cd" ]; then
656
+ shift
628
657
  local target
629
- target=$(forgemap pick) || return $?
630
- [ -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"
631
675
  return
632
676
  fi
633
- local matches
634
- matches=$(forgemap search "$1" --format path)
635
- if [ -z "$matches" ]; then
636
- echo "forgemap: no match for $1" >&2
637
- return 1
638
- fi
639
- local count
640
- count=$(printf '%s\\n' "$matches" | wc -l | tr -d ' ')
641
- if [ "$count" = "1" ]; then
642
- cd "$matches"
643
- else
644
- local target
645
- target=$(forgemap pick "$1") || return $?
646
- [ -n "$target" ] && cd "$target"
647
- fi
677
+ command forgemap "$@"
648
678
  }
649
679
  `;
650
680
  }
651
- function renderFish(fnName) {
681
+ function renderFish(name) {
652
682
  return `# forgemap shell integration — drop into your ~/.config/fish/config.fish:
653
683
  # forgemap shell-init fish | source
654
684
 
655
- function ${fnName}
656
- if test (count $argv) -eq 0
657
- set target (forgemap pick); or return $status
658
- if test -n "$target"
659
- 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
660
702
  end
703
+ test -n "$target"; and builtin cd $target
661
704
  return
662
705
  end
663
- set matches (forgemap search $argv[1] --format path)
664
- if test -z "$matches"
665
- echo "forgemap: no match for $argv[1]" >&2
666
- return 1
667
- end
668
- set count (count $matches)
669
- if test $count -eq 1
670
- cd $matches[1]
671
- else
672
- set target (forgemap pick $argv[1]); or return $status
673
- if test -n "$target"
674
- cd "$target"
675
- end
676
- end
706
+ command forgemap $argv
677
707
  end
678
708
  `;
679
709
  }
680
710
  const shellInitCommand = defineCommand({
681
711
  meta: {
682
712
  name: "shell-init",
683
- 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)"`.'
684
714
  },
685
715
  args: {
686
716
  shell: {
@@ -690,8 +720,8 @@ const shellInitCommand = defineCommand({
690
720
  },
691
721
  name: {
692
722
  type: "string",
693
- description: "Name of the generated shell function",
694
- default: "fcd"
723
+ description: "Name of the generated wrapper function (default: forgemap)",
724
+ default: "forgemap"
695
725
  }
696
726
  },
697
727
  async run({ args }) {
@@ -703,8 +733,8 @@ const shellInitCommand = defineCommand({
703
733
  process.exitCode = 1;
704
734
  return;
705
735
  }
706
- const fnName = args.name || "fcd";
707
- const out = requested === "fish" ? renderFish(fnName) : renderPosix(fnName);
736
+ const name = args.name || "forgemap";
737
+ const out = requested === "fish" ? renderFish(name) : renderPosix(name);
708
738
  process.stdout.write(out);
709
739
  }
710
740
  });
@@ -715,6 +745,7 @@ const rootCommand = defineCommand({
715
745
  },
716
746
  subCommands: {
717
747
  clone: cloneCommand,
748
+ cd: cdCommand,
718
749
  path: pathCommand,
719
750
  open: openCommand,
720
751
  search: searchCommand,
@@ -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/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 { 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(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 { 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 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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"}
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.20-4352c3f",
4
+ "version": "0.1.0-dev.22-d31fc67",
5
5
  "description": "CLI that manages a local repo layout grouped by git server, organization and repository name.",
6
6
  "keywords": [
7
7
  "cli",
@@ -49,6 +49,7 @@
49
49
  "citty": "^0.1.6",
50
50
  "consola": "^3.4.0",
51
51
  "defu": "^6.1.4",
52
+ "forgemap": "link:",
52
53
  "fuse.js": "^7.3.0",
53
54
  "pathe": "^2.0.0"
54
55
  },