@spader/dotllm 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,31 +1,31 @@
1
1
  {
2
2
  "name": "@spader/dotllm",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "A simple CLI to clone, manage, and link repositories for LLM reference",
5
5
  "type": "module",
6
- "bin": {
7
- "dotllm": "src/cli/index.ts"
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/tspader/dotllm"
8
9
  },
9
- "scripts": {
10
- "check": "bunx tsc --noEmit",
11
- "prepublishOnly": "bun run check"
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "bin": {
14
+ "dotllm": "src/cli/index.js"
12
15
  },
13
16
  "files": [
14
- "src/**/*.ts",
17
+ "src/**/*.js",
15
18
  "README.md"
16
19
  ],
17
20
  "exports": {
18
- "./cli": "./src/cli/index.ts",
19
- "./cli/*": "./src/cli/*.ts",
20
- "./core": "./src/core/index.ts",
21
- "./core/*": "./src/core/*.ts"
21
+ "./cli": "./src/cli/index.js",
22
+ "./cli/*": "./src/cli/*.js",
23
+ "./core": "./src/core/index.js",
24
+ "./core/*": "./src/core/*.js"
22
25
  },
23
26
  "engines": {
24
27
  "bun": ">=1.1.0"
25
28
  },
26
- "publishConfig": {
27
- "access": "public"
28
- },
29
29
  "keywords": [
30
30
  "cli",
31
31
  "bun",
@@ -39,9 +39,5 @@
39
39
  "picocolors": "^1.1.1",
40
40
  "yargs": "^17.7.2",
41
41
  "zod": "^4.3.6"
42
- },
43
- "devDependencies": {
44
- "@types/bun": "latest",
45
- "@types/yargs": "^17.0.33"
46
42
  }
47
43
  }
@@ -1,177 +1,185 @@
1
+ // @bun
2
+ // src/cli/commands/add.ts
1
3
  import fs from "fs";
2
4
  import path from "path";
3
5
  import * as prompts from "@clack/prompts";
4
6
  import { z } from "zod";
5
- import { add } from "@spader/dotllm/core";
7
+ import { add, Config, sync } from "@spader/dotllm/core";
6
8
  import { defaultTheme as t } from "@spader/dotllm/cli/theme";
7
- import type { CommandDef } from "@spader/dotllm/cli/yargs";
8
-
9
- const RepoShape = z.object({
10
- description: z.string().nullable().optional(),
9
+ import { Prompt } from "@spader/dotllm/cli/prompt";
10
+ var RepoShape = z.object({
11
+ description: z.string().nullable().optional()
11
12
  });
12
-
13
- function isUrl(value: string): boolean {
14
- return value.startsWith("http://") ||
15
- value.startsWith("https://") ||
16
- value.startsWith("git@") ||
17
- value.startsWith("ssh://");
13
+ function isUrl(value) {
14
+ return value.startsWith("http://") || value.startsWith("https://") || value.startsWith("git@") || value.startsWith("ssh://");
18
15
  }
19
-
20
- function stem(value: string): string {
16
+ function stem(value) {
21
17
  const clean = value.trim().replace(/\/+$/, "");
22
- if (clean.length === 0) return "";
23
-
18
+ if (clean.length === 0)
19
+ return "";
24
20
  if (clean.startsWith("git@")) {
25
21
  const raw = clean.split(":").slice(1).join(":");
26
22
  const seg = raw.split("/").filter(Boolean).pop() ?? raw;
27
23
  return seg.replace(/\.git$/, "");
28
24
  }
29
-
30
25
  if (isUrl(clean)) {
31
26
  const seg = clean.split("/").filter(Boolean).pop() ?? clean;
32
27
  const raw = seg.split("?")[0] ?? seg;
33
28
  const full = raw.split("#")[0] ?? raw;
34
29
  return full.replace(/\.git$/, "");
35
30
  }
36
-
37
31
  const base = path.basename(clean);
38
32
  const parsed = path.parse(base);
39
- if (parsed.name.length > 0) return parsed.name;
33
+ if (parsed.name.length > 0)
34
+ return parsed.name;
40
35
  return base;
41
36
  }
42
-
43
- function github(uri: string): { owner: string; repo: string } | null {
37
+ function github(uri) {
44
38
  const https = uri.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
45
39
  if (https) {
46
- return { owner: https[1]!, repo: https[2]! };
40
+ return { owner: https[1], repo: https[2] };
47
41
  }
48
-
49
42
  const ssh = uri.match(/^ssh:\/\/git@github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
50
43
  if (ssh) {
51
- return { owner: ssh[1]!, repo: ssh[2]! };
44
+ return { owner: ssh[1], repo: ssh[2] };
52
45
  }
53
-
54
46
  const scp = uri.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);
55
47
  if (scp) {
56
- return { owner: scp[1]!, repo: scp[2]! };
48
+ return { owner: scp[1], repo: scp[2] };
57
49
  }
58
-
59
50
  return null;
60
51
  }
61
-
62
- function gitName(uri: string): string {
52
+ function gitName(uri) {
63
53
  const dir = path.resolve(uri);
64
- if (!fs.existsSync(dir)) return "";
65
- if (!fs.statSync(dir).isDirectory()) return "";
66
-
54
+ if (!fs.existsSync(dir))
55
+ return "";
56
+ if (!fs.statSync(dir).isDirectory())
57
+ return "";
67
58
  const proc = Bun.spawnSync(["git", "remote", "get-url", "origin"], {
68
59
  cwd: dir,
69
60
  stdout: "pipe",
70
- stderr: "pipe",
61
+ stderr: "pipe"
71
62
  });
72
- if (proc.exitCode !== 0) return "";
73
-
63
+ if (proc.exitCode !== 0)
64
+ return "";
74
65
  const out = proc.stdout.toString().trim();
75
- if (out.length === 0) return "";
66
+ if (out.length === 0)
67
+ return "";
76
68
  return stem(out);
77
69
  }
78
-
79
- async function remoteDescription(uri: string): Promise<string> {
70
+ async function remoteDescription(uri) {
80
71
  const repo = github(uri);
81
- if (!repo) return "";
82
-
72
+ if (!repo)
73
+ return "";
83
74
  const url = `https://api.github.com/repos/${repo.owner}/${repo.repo}`;
84
75
  const response = await fetch(url, {
85
76
  headers: {
86
77
  accept: "application/vnd.github+json",
87
- "user-agent": "dotllm",
88
- },
78
+ "user-agent": "dotllm"
79
+ }
89
80
  });
90
- if (!response.ok) return "";
91
-
81
+ if (!response.ok)
82
+ return "";
92
83
  const raw = await response.json();
93
84
  const result = RepoShape.safeParse(raw);
94
- if (!result.success) return "";
85
+ if (!result.success)
86
+ return "";
95
87
  return result.data.description ?? "";
96
88
  }
97
-
98
- async function prefill(uri: string): Promise<{ name: string; description: string }> {
89
+ async function prefill(uri) {
99
90
  const remote = isUrl(uri);
100
91
  const git = remote ? "" : gitName(uri);
101
92
  const name = git.length > 0 ? git : stem(uri);
102
93
  const description = remote ? await remoteDescription(uri) : "";
103
94
  return { name, description };
104
95
  }
105
-
106
- async function interactive(): Promise<void> {
96
+ async function interactive(namePrefill, descPrefill) {
107
97
  const uri = await prompts.text({
108
- message: "URL or local path to a git repo",
98
+ message: "URL or local path to a git repo"
109
99
  });
110
- if (prompts.isCancel(uri)) return;
111
-
100
+ if (prompts.isCancel(uri))
101
+ return;
112
102
  const input = uri.trim();
113
103
  const seed = await prefill(input);
114
-
115
104
  const name = await prompts.text({
116
- message: "Name (leave empty to auto-detect)",
117
- defaultValue: seed.name,
105
+ message: "Name",
106
+ initialValue: namePrefill ?? seed.name
118
107
  });
119
- if (prompts.isCancel(name)) return;
120
-
108
+ if (prompts.isCancel(name))
109
+ return;
121
110
  const description = await prompts.text({
122
111
  message: "Description",
123
- defaultValue: seed.description,
112
+ initialValue: descPrefill ?? seed.description
124
113
  });
125
- if (prompts.isCancel(description)) return;
126
-
114
+ if (prompts.isCancel(description))
115
+ return;
127
116
  await run(input, name || undefined, description || undefined);
128
117
  }
129
-
130
- async function run(uri: string, name?: string, description?: string): Promise<void> {
131
- const spinner = prompts.spinner();
132
- spinner.start(`Adding ${uri}`);
133
-
134
- const result = await add(uri, name, description);
118
+ function autoLink(name) {
119
+ const localFile = path.join(".llm", "dotllm.json");
120
+ if (!fs.existsSync(localFile))
121
+ return;
122
+ const local = Config.Local.read();
123
+ if (Config.Local.has(local, name))
124
+ return;
125
+ const global = Config.Global.read();
126
+ const repo = Config.Global.find(global, name);
127
+ if (!repo)
128
+ return;
129
+ Config.Local.write(Config.Local.add(local, repo));
130
+ Prompt.sync(sync());
131
+ }
132
+ async function run(uri, name, description) {
133
+ const spinner2 = prompts.spinner();
134
+ spinner2.start(`Adding ${uri}`);
135
+ const needSeed = !name || !description;
136
+ const seed = needSeed ? await prefill(uri) : { name: "", description: "" };
137
+ const resolved = name ?? seed.name;
138
+ const desc = description ?? seed.description;
139
+ const result = await add(uri, resolved || undefined, desc || undefined);
135
140
  if (!result.ok) {
136
- spinner.stop(t.error(result.error), 1);
141
+ spinner2.stop(t.error(result.error), 1);
137
142
  process.exit(1);
138
143
  return;
139
144
  }
140
-
141
- spinner.stop(`${t.success("added")} ${t.primary(result.entry.name)} ${t.link(result.storePath)}`);
145
+ spinner2.stop(`${t.success("added")} ${t.primary(result.entry.name)} ${t.link(result.storePath)}`);
146
+ autoLink(result.entry.name);
142
147
  }
143
-
144
- export const command: CommandDef = {
148
+ var command = {
145
149
  description: "Register a git repo as a reference",
146
150
  summary: "Add a repo to the registry",
147
151
  positionals: {
148
152
  uri: {
149
153
  type: "string",
150
- description: "URL or local path to a git repo",
151
- },
154
+ description: "URL or local path to a git repo"
155
+ }
152
156
  },
153
157
  options: {
154
158
  name: {
155
159
  alias: "n",
156
160
  type: "string",
157
- description: "Name override (defaults to repo name from git)",
161
+ description: "Name override (defaults to repo name from git)"
158
162
  },
159
163
  description: {
160
164
  alias: "d",
161
165
  type: "string",
162
- description: "Description of the reference",
163
- },
166
+ description: "Description of the reference"
167
+ }
164
168
  },
165
169
  handler: async (argv) => {
170
+ prompts.intro("dotllm add");
166
171
  const uri = typeof argv.uri === "string" && argv.uri.length > 0 ? argv.uri : undefined;
167
-
172
+ const name = typeof argv.name === "string" && argv.name.length > 0 ? argv.name : undefined;
173
+ const description = typeof argv.description === "string" && argv.description.length > 0 ? argv.description : undefined;
168
174
  if (!uri) {
169
- await interactive();
175
+ await interactive(name, description);
170
176
  return;
171
177
  }
172
-
173
- const name = typeof argv.name === "string" && argv.name.length > 0 ? argv.name : undefined;
174
- const description = typeof argv.description === "string" ? argv.description : undefined;
175
178
  await run(uri, name, description);
176
- },
179
+ }
180
+ };
181
+ export {
182
+ stem,
183
+ github,
184
+ command
177
185
  };
@@ -0,0 +1,45 @@
1
+ // @bun
2
+ // src/cli/commands/cd.ts
3
+ import path from "path";
4
+ import fs from "fs";
5
+ import { Config } from "@spader/dotllm/core";
6
+ import { defaultTheme as t } from "@spader/dotllm/cli/theme";
7
+ var command = {
8
+ description: "Open a subshell in a repo's store directory",
9
+ summary: "cd into a repo",
10
+ positionals: {
11
+ name: {
12
+ type: "string",
13
+ description: "Name of the repo",
14
+ required: true
15
+ }
16
+ },
17
+ handler: async (argv) => {
18
+ const name = String(argv.name);
19
+ const global = Config.Global.read();
20
+ const repo = Config.Global.find(global, name);
21
+ if (!repo) {
22
+ console.error(t.error(`No repo named "${name}" in registry`));
23
+ process.exit(1);
24
+ return;
25
+ }
26
+ const dir = path.join(Config.storeDir(), name);
27
+ if (!fs.existsSync(dir)) {
28
+ console.error(t.error(`Store path does not exist: ${dir}`));
29
+ process.exit(1);
30
+ return;
31
+ }
32
+ const shell = process.env.SHELL ?? "/bin/sh";
33
+ const proc = Bun.spawn([shell], {
34
+ cwd: dir,
35
+ stdin: "inherit",
36
+ stdout: "inherit",
37
+ stderr: "inherit"
38
+ });
39
+ const code = await proc.exited;
40
+ process.exit(code);
41
+ }
42
+ };
43
+ export {
44
+ command
45
+ };
@@ -0,0 +1,18 @@
1
+ // @bun
2
+ // src/cli/commands/index.ts
3
+ import { command } from "@spader/dotllm/cli/commands/add";
4
+ import { command as command2 } from "@spader/dotllm/cli/commands/remove";
5
+ import { command as command3 } from "@spader/dotllm/cli/commands/list";
6
+ import { command as command4 } from "@spader/dotllm/cli/commands/link";
7
+ import { command as command5 } from "@spader/dotllm/cli/commands/sync";
8
+ import { command as command6 } from "@spader/dotllm/cli/commands/which";
9
+ import { command as command7 } from "@spader/dotllm/cli/commands/cd";
10
+ export {
11
+ command6 as which,
12
+ command5 as sync,
13
+ command2 as remove,
14
+ command3 as list,
15
+ command4 as link,
16
+ command7 as cd,
17
+ command as add
18
+ };
@@ -0,0 +1,78 @@
1
+ // @bun
2
+ // src/cli/commands/link.ts
3
+ import * as prompts from "@clack/prompts";
4
+ import { Config, link, unlink, sync } from "@spader/dotllm/core";
5
+ import { defaultTheme as t } from "@spader/dotllm/cli/theme";
6
+ import { Prompt } from "@spader/dotllm/cli/prompt";
7
+ var command = {
8
+ description: "Interactively pick repos to link into .llm/reference/, or add/remove one by name",
9
+ summary: "Link references",
10
+ positionals: {
11
+ name: {
12
+ type: "string",
13
+ description: "Name of the repo to link, or omit for interactive"
14
+ }
15
+ },
16
+ options: {
17
+ remove: {
18
+ alias: "r",
19
+ type: "boolean",
20
+ description: "Remove the link instead of adding it"
21
+ }
22
+ },
23
+ handler: async (argv) => {
24
+ prompts.intro("dotllm link");
25
+ const name = typeof argv.name === "string" && argv.name.length > 0 ? argv.name : undefined;
26
+ const shouldRemove = argv.remove === true;
27
+ if (name) {
28
+ if (shouldRemove) {
29
+ const result = unlink(name);
30
+ if (!result.ok) {
31
+ prompts.log.error(t.error(result.error));
32
+ process.exit(1);
33
+ return;
34
+ }
35
+ prompts.log.step(`unlinked ${t.primary(name)}`);
36
+ return;
37
+ }
38
+ const global2 = Config.Global.read();
39
+ const repo = Config.Global.find(global2, name);
40
+ if (!repo) {
41
+ prompts.log.error(t.error(`No repo named "${name}" in registry`));
42
+ process.exit(1);
43
+ return;
44
+ }
45
+ const local2 = Config.Local.read();
46
+ Config.Local.write(Config.Local.add(local2, repo));
47
+ Prompt.sync(sync());
48
+ return;
49
+ }
50
+ const global = Config.Global.read();
51
+ if (global.repos.length === 0) {
52
+ console.log(t.dim("(no repos registered)"));
53
+ console.log(t.dim("use `dotllm add <path>` to register one"));
54
+ return;
55
+ }
56
+ const local = Config.Local.read();
57
+ const current = new Set(Object.keys(local.refs));
58
+ const selected = await prompts.multiselect({
59
+ message: "Select repos to link into .llm/reference/",
60
+ options: global.repos.map((r) => ({
61
+ value: r.name,
62
+ label: r.name,
63
+ hint: r.uri
64
+ })),
65
+ initialValues: global.repos.filter((r) => current.has(r.name)).map((r) => r.name),
66
+ required: false
67
+ });
68
+ if (prompts.isCancel(selected)) {
69
+ prompts.cancel("cancelled");
70
+ return;
71
+ }
72
+ const names = Array.isArray(selected) ? selected.filter((value) => typeof value === "string") : [];
73
+ Prompt.sync(link(names));
74
+ }
75
+ };
76
+ export {
77
+ command
78
+ };
@@ -0,0 +1,42 @@
1
+ // @bun
2
+ // src/cli/commands/list.ts
3
+ import * as prompts from "@clack/prompts";
4
+ import { Config } from "@spader/dotllm/core";
5
+ import { table } from "@spader/dotllm/cli/layout";
6
+ import { defaultTheme as t } from "@spader/dotllm/cli/theme";
7
+ var command = {
8
+ description: "List all registered repos",
9
+ summary: "Show the registry",
10
+ handler: () => {
11
+ prompts.intro("dotllm list");
12
+ const global = Config.Global.read();
13
+ if (global.repos.length === 0) {
14
+ console.log(t.dim("(no repos registered)"));
15
+ console.log(t.dim("use `dotllm add <path>` to register one"));
16
+ return;
17
+ }
18
+ const local = Config.Local.read();
19
+ const linked = new Set(Object.keys(local.refs));
20
+ table(["name", "kind", "uri", "description", "linked"], [
21
+ global.repos.map((r) => r.name),
22
+ global.repos.map((r) => r.kind),
23
+ global.repos.map((r) => r.uri),
24
+ global.repos.map((r) => r.description),
25
+ global.repos.map((r) => linked.has(r.name) ? "yes" : "no")
26
+ ], {
27
+ flex: [0, 0, 1, 1, 0],
28
+ noTruncate: [true, true, false, false, true],
29
+ truncate: ["end", "end", "start", "end", "end"],
30
+ format: [
31
+ (s) => t.primary(s),
32
+ (s) => s,
33
+ (s) => t.link(s),
34
+ (s) => s,
35
+ (s) => s.trim() === "yes" ? t.success(s) : s
36
+ ]
37
+ });
38
+ }
39
+ };
40
+ export {
41
+ command
42
+ };
@@ -1,28 +1,30 @@
1
- import { log } from "@clack/prompts";
1
+ // @bun
2
+ // src/cli/commands/remove.ts
3
+ import * as prompts from "@clack/prompts";
2
4
  import { remove } from "@spader/dotllm/core";
3
5
  import { defaultTheme as t } from "@spader/dotllm/cli/theme";
4
- import type { CommandDef } from "@spader/dotllm/cli/yargs";
5
-
6
- export const command: CommandDef = {
6
+ var command = {
7
7
  description: "Remove a repo from the registry",
8
8
  summary: "Remove a registered repo",
9
9
  positionals: {
10
10
  name: {
11
11
  type: "string",
12
12
  description: "Name of the reference to remove",
13
- required: true,
14
- },
13
+ required: true
14
+ }
15
15
  },
16
16
  handler: (argv) => {
17
+ prompts.intro("dotllm remove");
17
18
  const name = String(argv.name);
18
-
19
19
  const result = remove(name);
20
20
  if (!result.ok) {
21
- log.error(t.error(result.error));
21
+ prompts.log.error(t.error(result.error));
22
22
  process.exit(1);
23
23
  return;
24
24
  }
25
-
26
- log.step(`removed ${t.primary(name)}`);
27
- },
25
+ prompts.log.step(`removed ${t.primary(name)}`);
26
+ }
27
+ };
28
+ export {
29
+ command
28
30
  };
@@ -1,45 +1,36 @@
1
+ // @bun
2
+ // src/cli/commands/sync.ts
1
3
  import * as prompts from "@clack/prompts";
2
4
  import { pull, sync } from "@spader/dotllm/core";
3
5
  import { defaultTheme as t } from "@spader/dotllm/cli/theme";
4
- import type { CommandDef } from "@spader/dotllm/cli/yargs";
5
-
6
- export const command: CommandDef = {
6
+ import { Prompt } from "@spader/dotllm/cli/prompt";
7
+ var command = {
7
8
  description: "Re-create symlinks from .llm/dotllm.json",
8
9
  summary: "Sync symlinks from local config",
9
10
  handler: async () => {
11
+ prompts.intro("dotllm sync");
10
12
  const result = sync();
11
-
12
13
  if (result.linked.length === 0 && result.removed.length === 0 && result.missing.length === 0 && result.unchanged.length === 0) {
13
14
  console.log(t.dim("(no refs in local config)"));
14
15
  console.log(t.dim("use `dotllm link` to select repos"));
15
16
  return;
16
17
  }
17
-
18
- for (const name of result.removed) {
19
- prompts.log.step(`removed stale ${t.primary(name)}`);
20
- }
21
- for (const name of result.missing) {
22
- prompts.log.warn(`${t.primary(name)} missing cache entry`);
23
- }
24
- for (const name of result.linked) {
25
- prompts.log.step(`linked ${t.primary(name)} -> ${t.link(`.llm/reference/${name}`)}`);
26
- }
27
-
18
+ Prompt.sync(result);
28
19
  const refs = [...new Set([...result.unchanged, ...result.linked])];
29
20
  if (refs.length === 0) {
30
21
  return;
31
22
  }
32
-
33
- const spinner = prompts.spinner();
34
- spinner.start(`Pulling ${refs.length} linked repo${refs.length === 1 ? "" : "s"}`);
35
-
23
+ const spinner2 = prompts.spinner();
24
+ spinner2.start(`Pulling ${refs.length} linked repo${refs.length === 1 ? "" : "s"}`);
36
25
  const pulled = await pull(refs);
37
26
  if (pulled.failed.length > 0) {
38
- spinner.stop(t.error(`pull failed for ${pulled.failed.length} repo${pulled.failed.length === 1 ? "" : "s"}`), 1);
27
+ spinner2.stop(t.error(`pull failed for ${pulled.failed.length} repo${pulled.failed.length === 1 ? "" : "s"}`), 1);
39
28
  process.exit(1);
40
29
  return;
41
30
  }
42
-
43
- spinner.stop(`${t.success("pulled")} ${pulled.count} repo${pulled.count === 1 ? "" : "s"}`);
44
- },
31
+ spinner2.stop(`${t.success("pulled")} ${pulled.count} repo${pulled.count === 1 ? "" : "s"}`);
32
+ }
33
+ };
34
+ export {
35
+ command
45
36
  };
@@ -0,0 +1,30 @@
1
+ // @bun
2
+ // src/cli/commands/which.ts
3
+ import path from "path";
4
+ import { Config } from "@spader/dotllm/core";
5
+ import { defaultTheme as t } from "@spader/dotllm/cli/theme";
6
+ var command = {
7
+ description: "Print the absolute path to a repo in the store",
8
+ summary: "Show repo store path",
9
+ positionals: {
10
+ name: {
11
+ type: "string",
12
+ description: "Name of the repo",
13
+ required: true
14
+ }
15
+ },
16
+ handler: (argv) => {
17
+ const name = String(argv.name);
18
+ const global = Config.Global.read();
19
+ const repo = Config.Global.find(global, name);
20
+ if (!repo) {
21
+ console.error(t.error(`No repo named "${name}" in registry`));
22
+ process.exit(1);
23
+ return;
24
+ }
25
+ console.log(path.join(Config.storeDir(), name));
26
+ }
27
+ };
28
+ export {
29
+ command
30
+ };
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+
4
+ // src/cli/index.ts
5
+ import { build } from "@spader/dotllm/cli/yargs";
6
+ import { add, remove, list, link, sync, which, cd } from "@spader/dotllm/cli/commands/index";
7
+ var DotLlmCli;
8
+ ((DotLlmCli) => {
9
+ DotLlmCli.def = {
10
+ name: "dotllm",
11
+ description: "Manage git repo references symlinked into .llm/reference/",
12
+ commands: {
13
+ add,
14
+ remove,
15
+ list,
16
+ link,
17
+ sync,
18
+ which,
19
+ cd
20
+ }
21
+ };
22
+ function run() {
23
+ build(DotLlmCli.def).parse();
24
+ }
25
+ DotLlmCli.run = run;
26
+ })(DotLlmCli ||= {});
27
+ DotLlmCli.run();
28
+ export {
29
+ DotLlmCli
30
+ };