@spader/dotllm 1.3.2 → 1.3.4

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
@@ -39,3 +39,15 @@ Check in `.llm/dotllm.json`. Then, on a fresh clone, link the repositories to yo
39
39
  ```bash
40
40
  dotllm sync
41
41
  ```
42
+
43
+ # configuration
44
+ The registry lives at `~/.local/share/dotllm/dotllm.json` (`%LOCALAPPDATA%\dotllm\dotllm.json` on Windows). Set `store` to keep the repositories somewhere else, e.g. another drive
45
+
46
+ ```json
47
+ {
48
+ "store": "/mnt/big/llm",
49
+ "repos": []
50
+ }
51
+ ```
52
+
53
+ `~` is expanded, and a relative path resolves against the config directory. Existing repositories are not moved; either move them yourself or `dotllm sync` to re-clone.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spader/dotllm",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "A simple CLI to clone, manage, and link repositories for LLM reference",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,20 +1,527 @@
1
1
  // @bun
2
- var __require = import.meta.require;
2
+ var __esm = (fn, res, err) => () => {
3
+ if (fn)
4
+ try {
5
+ res = fn(fn = 0);
6
+ } catch (e) {
7
+ err = [e];
8
+ }
9
+ if (err)
10
+ throw err[0];
11
+ return res;
12
+ };
3
13
 
4
- // src/cli/commands/add.ts
14
+ // src/core/config.ts
5
15
  import fs from "fs";
16
+ import os from "os";
6
17
  import path from "path";
7
- import * as prompts from "@clack/prompts";
8
18
  import { z } from "zod";
9
- import { add, Config, sync } from "@spader/dotllm/core";
10
- import { defaultTheme as t } from "@spader/dotllm/cli/theme";
11
- import { Prompt } from "@spader/dotllm/cli/prompt";
12
- var RepoShape = z.object({
13
- description: z.string().nullable().optional()
19
+ function readJson(filepath) {
20
+ if (!fs.existsSync(filepath))
21
+ return null;
22
+ const raw = fs.readFileSync(filepath, "utf-8");
23
+ try {
24
+ return JSON.parse(raw);
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+ var LOCAL_DIR = ".llm", LOCAL_FILE, REF_DIR, RepoEntry, GlobalShape, LocalShape, Config;
30
+ var init_config = __esm(() => {
31
+ LOCAL_FILE = path.join(LOCAL_DIR, "dotllm.json");
32
+ REF_DIR = path.join(LOCAL_DIR, "reference");
33
+ RepoEntry = z.object({
34
+ kind: z.enum(["url", "file"]),
35
+ name: z.string(),
36
+ uri: z.string(),
37
+ description: z.string()
38
+ });
39
+ GlobalShape = z.object({
40
+ store: z.string().optional(),
41
+ repos: z.array(RepoEntry)
42
+ });
43
+ LocalShape = z.object({
44
+ refs: z.record(z.string(), RepoEntry)
45
+ });
46
+ ((Config) => {
47
+ function home() {
48
+ if (process.platform === "win32") {
49
+ const appData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local");
50
+ return path.join(appData, "dotllm");
51
+ }
52
+ return path.join(process.env.HOME ?? os.homedir(), ".local", "share", "dotllm");
53
+ }
54
+ Config.home = home;
55
+ function storeDir() {
56
+ const store = Global.read().store;
57
+ if (!store)
58
+ return path.join(home(), "store");
59
+ return expand(store);
60
+ }
61
+ Config.storeDir = storeDir;
62
+ function refDir() {
63
+ return REF_DIR;
64
+ }
65
+ Config.refDir = refDir;
66
+ let Global;
67
+ ((Global) => {
68
+ function read() {
69
+ const raw = readJson(path.join(home(), "dotllm.json"));
70
+ if (!raw)
71
+ return { repos: [] };
72
+ const result = GlobalShape.safeParse(raw);
73
+ if (!result.success)
74
+ return { repos: [] };
75
+ return result.data;
76
+ }
77
+ Global.read = read;
78
+ function write(config) {
79
+ const dir = home();
80
+ fs.mkdirSync(dir, { recursive: true });
81
+ fs.writeFileSync(path.join(dir, "dotllm.json"), JSON.stringify(config, null, 2) + `
82
+ `);
83
+ }
84
+ Global.write = write;
85
+ function find(config, name) {
86
+ const lower = name.toLowerCase();
87
+ return config.repos.find((r) => r.name.toLowerCase() === lower);
88
+ }
89
+ Global.find = find;
90
+ function add(config, entry) {
91
+ const lower = entry.name.toLowerCase();
92
+ const filtered = config.repos.filter((r) => r.name.toLowerCase() !== lower);
93
+ return { ...config, repos: [...filtered, entry] };
94
+ }
95
+ Global.add = add;
96
+ function remove(config, name) {
97
+ const lower = name.toLowerCase();
98
+ return { ...config, repos: config.repos.filter((r) => r.name.toLowerCase() !== lower) };
99
+ }
100
+ Global.remove = remove;
101
+ })(Global = Config.Global ||= {});
102
+ let Local;
103
+ ((Local) => {
104
+ function read() {
105
+ const raw = readJson(LOCAL_FILE);
106
+ if (!raw)
107
+ return { refs: {} };
108
+ const result = LocalShape.safeParse(raw);
109
+ if (!result.success)
110
+ return { refs: {} };
111
+ return result.data;
112
+ }
113
+ Local.read = read;
114
+ function write(config) {
115
+ fs.mkdirSync(LOCAL_DIR, { recursive: true });
116
+ fs.writeFileSync(LOCAL_FILE, JSON.stringify(config, null, 2) + `
117
+ `);
118
+ }
119
+ Local.write = write;
120
+ function find(config, name) {
121
+ const lower = name.toLowerCase();
122
+ for (const [key, value] of Object.entries(config.refs)) {
123
+ if (key.toLowerCase() === lower)
124
+ return value;
125
+ }
126
+ return;
127
+ }
128
+ Local.find = find;
129
+ function has(config, name) {
130
+ return find(config, name) !== undefined;
131
+ }
132
+ Local.has = has;
133
+ function add(config, repo) {
134
+ const lower = repo.name.toLowerCase();
135
+ const refs = Object.fromEntries(Object.entries(config.refs).filter(([key]) => key.toLowerCase() !== lower));
136
+ refs[repo.name] = repo;
137
+ return { refs };
138
+ }
139
+ Local.add = add;
140
+ function remove(config, name) {
141
+ const lower = name.toLowerCase();
142
+ const refs = Object.fromEntries(Object.entries(config.refs).filter(([key]) => key.toLowerCase() !== lower));
143
+ return { refs };
144
+ }
145
+ Local.remove = remove;
146
+ })(Local = Config.Local ||= {});
147
+ function expand(dir) {
148
+ const tilde = dir === "~" || dir.startsWith("~/") || dir.startsWith("~\\");
149
+ if (!tilde)
150
+ return path.resolve(home(), dir);
151
+ return path.join(os.homedir(), dir.slice(1));
152
+ }
153
+ })(Config ||= {});
14
154
  });
155
+
156
+ // src/core/add.ts
157
+ import fs2 from "fs";
158
+ import path2 from "path";
15
159
  function isUrl(value) {
16
160
  return value.startsWith("http://") || value.startsWith("https://") || value.startsWith("git@") || value.startsWith("ssh://");
17
161
  }
162
+ function nameFromGitRemote(dir) {
163
+ const result = Bun.spawnSync(["git", "remote", "get-url", "origin"], {
164
+ cwd: dir,
165
+ stdout: "pipe",
166
+ stderr: "pipe"
167
+ });
168
+ if (result.exitCode !== 0)
169
+ return null;
170
+ const url = result.stdout.toString().trim();
171
+ return nameFromUrl(url);
172
+ }
173
+ function nameFromUrl(url) {
174
+ const base = url.split("/").pop() ?? url;
175
+ return base.replace(/\.git$/, "");
176
+ }
177
+ async function add(uri, name, description) {
178
+ const desc = description ?? "";
179
+ if (isUrl(uri)) {
180
+ return cloneUrl(uri, name, desc);
181
+ }
182
+ return linkLocal(uri, name, desc);
183
+ }
184
+ async function cloneUrl(url, name, description) {
185
+ const resolved = name ?? nameFromUrl(url);
186
+ const store = Config.storeDir();
187
+ fs2.mkdirSync(store, { recursive: true });
188
+ const target = path2.join(store, resolved);
189
+ if (!fs2.existsSync(target)) {
190
+ const proc = Bun.spawn(["git", "clone", "--depth=1", url, target], {
191
+ stdout: "pipe",
192
+ stderr: "pipe"
193
+ });
194
+ const code = await proc.exited;
195
+ if (code !== 0) {
196
+ const msg = await new Response(proc.stderr).text();
197
+ return { ok: false, error: `git clone failed: ${msg.trim()}` };
198
+ }
199
+ }
200
+ const entry = { kind: "url", name: resolved, uri: url, description };
201
+ const global = Config.Global.read();
202
+ Config.Global.write(Config.Global.add(global, entry));
203
+ return { ok: true, entry, storePath: target };
204
+ }
205
+ function linkLocal(raw, name, description) {
206
+ const resolved = path2.resolve(raw);
207
+ if (!fs2.existsSync(resolved)) {
208
+ return { ok: false, error: `Path does not exist: ${resolved}` };
209
+ }
210
+ if (!fs2.statSync(resolved).isDirectory()) {
211
+ return { ok: false, error: `Not a directory: ${resolved}` };
212
+ }
213
+ const store = Config.storeDir();
214
+ fs2.mkdirSync(store, { recursive: true });
215
+ const finalName = name ?? nameFromGitRemote(resolved) ?? path2.basename(resolved);
216
+ const target = path2.join(store, finalName);
217
+ if (!fs2.existsSync(target)) {
218
+ fs2.symlinkSync(resolved, target, "dir");
219
+ }
220
+ const entry = { kind: "file", name: finalName, uri: resolved, description };
221
+ const global = Config.Global.read();
222
+ Config.Global.write(Config.Global.add(global, entry));
223
+ return { ok: true, entry, storePath: target };
224
+ }
225
+ var init_add = __esm(() => {
226
+ init_config();
227
+ });
228
+
229
+ // src/core/remove.ts
230
+ import fs3 from "fs";
231
+ import path3 from "path";
232
+ function remove(name) {
233
+ const global = Config.Global.read();
234
+ const found = Config.Global.find(global, name);
235
+ if (!found) {
236
+ return { ok: false, error: `No repo named "${name}" in registry` };
237
+ }
238
+ const target = path3.join(Config.storeDir(), found.name);
239
+ if (fs3.existsSync(target)) {
240
+ const stat = fs3.lstatSync(target);
241
+ if (stat.isSymbolicLink()) {
242
+ fs3.unlinkSync(target);
243
+ }
244
+ if (stat.isDirectory()) {
245
+ fs3.rmSync(target, { recursive: true, force: true });
246
+ }
247
+ }
248
+ Config.Global.write(Config.Global.remove(global, found.name));
249
+ return { ok: true };
250
+ }
251
+ var init_remove = __esm(() => {
252
+ init_config();
253
+ });
254
+
255
+ // src/core/sync.ts
256
+ import fs4 from "fs";
257
+ import path4 from "path";
258
+ function shouldPull(storeDir, force) {
259
+ if (force)
260
+ return true;
261
+ const head = path4.join(storeDir, ".git", "HEAD");
262
+ const headStat = fs4.statSync(head, { throwIfNoEntry: false });
263
+ if (!headStat)
264
+ return true;
265
+ const age = Date.now() - headStat.mtimeMs;
266
+ if (age < FRESH_MS)
267
+ return false;
268
+ if (age > STALE_MS)
269
+ return true;
270
+ const dirStat = fs4.statSync(storeDir, { throwIfNoEntry: false });
271
+ if (!dirStat)
272
+ return true;
273
+ return dirStat.atimeMs > headStat.mtimeMs;
274
+ }
275
+ async function pull(names, options = {}) {
276
+ const force = options.force === true;
277
+ const global = Config.Global.read();
278
+ const states = await Promise.all(names.map(async (name) => {
279
+ const cwd = path4.join(Config.refDir(), name);
280
+ if (!fs4.existsSync(cwd)) {
281
+ return { kind: "failed", name, error: "reference directory missing" };
282
+ }
283
+ const repo = Config.Global.find(global, name);
284
+ if (repo && repo.kind === "file") {
285
+ return { kind: "skipped", name };
286
+ }
287
+ const storeDir = path4.join(Config.storeDir(), name);
288
+ const storeStat = fs4.lstatSync(storeDir, { throwIfNoEntry: false });
289
+ if (!storeStat || storeStat.isSymbolicLink()) {
290
+ return { kind: "skipped", name };
291
+ }
292
+ if (!fs4.existsSync(path4.join(storeDir, ".git"))) {
293
+ return { kind: "failed", name, error: "store directory is not a git repo" };
294
+ }
295
+ if (!shouldPull(storeDir, force)) {
296
+ return { kind: "skipped", name };
297
+ }
298
+ const fetch2 = Bun.spawn(["git", "fetch", "--depth=1", "origin", "HEAD"], {
299
+ cwd,
300
+ stdout: "pipe",
301
+ stderr: "pipe"
302
+ });
303
+ const [fetchCode, fetchOut, fetchErr] = await Promise.all([
304
+ fetch2.exited,
305
+ new Response(fetch2.stdout).text(),
306
+ new Response(fetch2.stderr).text()
307
+ ]);
308
+ if (fetchCode !== 0) {
309
+ const msg = `${fetchOut}
310
+ ${fetchErr}`.trim();
311
+ return { kind: "failed", name, error: msg || "git fetch failed" };
312
+ }
313
+ const reset = Bun.spawn(["git", "reset", "--hard", "FETCH_HEAD"], {
314
+ cwd,
315
+ stdout: "pipe",
316
+ stderr: "pipe"
317
+ });
318
+ const [resetCode, resetOut, resetErr] = await Promise.all([
319
+ reset.exited,
320
+ new Response(reset.stdout).text(),
321
+ new Response(reset.stderr).text()
322
+ ]);
323
+ if (resetCode !== 0) {
324
+ const msg = `${resetOut}
325
+ ${resetErr}`.trim();
326
+ return { kind: "failed", name, error: msg || "git reset failed" };
327
+ }
328
+ return { kind: "ok" };
329
+ }));
330
+ const pulled = [];
331
+ const skipped = [];
332
+ const failed = [];
333
+ for (let i = 0;i < states.length; i++) {
334
+ const state = states[i];
335
+ if (state.kind === "ok")
336
+ pulled.push(names[i]);
337
+ if (state.kind === "skipped")
338
+ skipped.push(state.name);
339
+ if (state.kind === "failed")
340
+ failed.push({ name: state.name, error: state.error });
341
+ }
342
+ return { count: names.length, pulled, skipped, failed };
343
+ }
344
+ function sync() {
345
+ const local = Config.Local.read();
346
+ const global = Config.Global.read();
347
+ const merged = Object.values(local.refs).reduce((config, repo) => Config.Global.add(config, repo), global);
348
+ if (Object.keys(local.refs).length > 0) {
349
+ Config.Global.write(merged);
350
+ }
351
+ const refDir = Config.refDir();
352
+ fs4.mkdirSync(refDir, { recursive: true });
353
+ fs4.mkdirSync(Config.storeDir(), { recursive: true });
354
+ const linked = [];
355
+ const removed = [];
356
+ const missing = [];
357
+ const unchanged = [];
358
+ const wanted = new Set(Object.keys(local.refs));
359
+ for (const entry of fs4.readdirSync(refDir)) {
360
+ if (wanted.has(entry))
361
+ continue;
362
+ const target = path4.join(refDir, entry);
363
+ const stat = fs4.lstatSync(target);
364
+ if (stat.isSymbolicLink()) {
365
+ fs4.unlinkSync(target);
366
+ removed.push(entry);
367
+ }
368
+ }
369
+ for (const [name, repo] of Object.entries(local.refs)) {
370
+ const store = path4.join(Config.storeDir(), name);
371
+ const storeBroken = repo.kind === "url" && fs4.existsSync(store) && !fs4.existsSync(path4.join(store, ".git"));
372
+ if (storeBroken) {
373
+ fs4.rmSync(store, { recursive: true, force: true });
374
+ }
375
+ if (!fs4.existsSync(store) && repo.kind === "url") {
376
+ const clone = Bun.spawnSync(["git", "clone", "--depth=1", repo.uri, store], {
377
+ stdout: "pipe",
378
+ stderr: "pipe"
379
+ });
380
+ if (clone.exitCode !== 0) {
381
+ missing.push(name);
382
+ continue;
383
+ }
384
+ }
385
+ if (!fs4.existsSync(store) && repo.kind === "file") {
386
+ if (!fs4.existsSync(repo.uri)) {
387
+ missing.push(name);
388
+ continue;
389
+ }
390
+ if (!fs4.statSync(repo.uri).isDirectory()) {
391
+ missing.push(name);
392
+ continue;
393
+ }
394
+ fs4.symlinkSync(repo.uri, store, "dir");
395
+ }
396
+ if (!fs4.existsSync(store)) {
397
+ missing.push(name);
398
+ continue;
399
+ }
400
+ const target = path4.join(refDir, name);
401
+ const stat = fs4.lstatSync(target, { throwIfNoEntry: false });
402
+ if (stat && !stat.isSymbolicLink()) {
403
+ unchanged.push(name);
404
+ continue;
405
+ }
406
+ if (stat && fs4.readlinkSync(target) === store) {
407
+ unchanged.push(name);
408
+ continue;
409
+ }
410
+ if (stat) {
411
+ fs4.unlinkSync(target);
412
+ }
413
+ fs4.symlinkSync(store, target, "dir");
414
+ linked.push(name);
415
+ }
416
+ return { linked, removed, missing, unchanged };
417
+ }
418
+ var FRESH_MS, STALE_MS;
419
+ var init_sync = __esm(() => {
420
+ init_config();
421
+ FRESH_MS = 24 * 60 * 60 * 1000;
422
+ STALE_MS = 7 * FRESH_MS;
423
+ });
424
+
425
+ // src/core/link.ts
426
+ function link(names) {
427
+ const global = Config.Global.read();
428
+ const rows = names.map((name) => {
429
+ const repo = Config.Global.find(global, name);
430
+ if (!repo)
431
+ return null;
432
+ return [repo.name, repo];
433
+ }).filter((row) => row !== null);
434
+ Config.Local.write({ refs: Object.fromEntries(rows) });
435
+ return sync();
436
+ }
437
+ var init_link = __esm(() => {
438
+ init_config();
439
+ init_sync();
440
+ });
441
+
442
+ // src/core/unlink.ts
443
+ import fs5 from "fs";
444
+ import path5 from "path";
445
+ function unlink(name) {
446
+ const local = Config.Local.read();
447
+ const found = Config.Local.find(local, name);
448
+ if (!found) {
449
+ return { ok: false, error: `"${name}" is not linked in local config` };
450
+ }
451
+ const target = path5.join(Config.refDir(), found.name);
452
+ if (fs5.lstatSync(target, { throwIfNoEntry: false })) {
453
+ fs5.unlinkSync(target);
454
+ }
455
+ Config.Local.write(Config.Local.remove(local, found.name));
456
+ return { ok: true };
457
+ }
458
+ var init_unlink = __esm(() => {
459
+ init_config();
460
+ });
461
+
462
+ // src/core/index.ts
463
+ var init_core = __esm(() => {
464
+ init_config();
465
+ init_add();
466
+ init_remove();
467
+ init_link();
468
+ init_unlink();
469
+ init_sync();
470
+ });
471
+
472
+ // src/cli/commands/add.ts
473
+ init_core();
474
+ import fs6 from "fs";
475
+ import path6 from "path";
476
+ import * as prompts2 from "@clack/prompts";
477
+ import { z as z2 } from "zod";
478
+
479
+ // src/cli/theme.ts
480
+ function rgb(r, g, b) {
481
+ return (value) => `\x1B[38;2;${r};${g};${b}m${value}\x1B[39m`;
482
+ }
483
+ var gray = (value) => rgb(value, value, value);
484
+ var defaultTheme = {
485
+ primary: rgb(114, 161, 136),
486
+ link: rgb(114, 140, 212),
487
+ header: gray(128),
488
+ command: rgb(114, 161, 136),
489
+ arg: rgb(161, 212, 212),
490
+ option: rgb(212, 212, 161),
491
+ type: gray(128),
492
+ description: (value) => value,
493
+ dim: gray(128),
494
+ error: rgb(212, 114, 114),
495
+ success: rgb(114, 212, 136)
496
+ };
497
+
498
+ // src/cli/prompt.ts
499
+ import * as prompts from "@clack/prompts";
500
+ var Prompt;
501
+ ((Prompt) => {
502
+ function sync(result) {
503
+ const parts = [];
504
+ if (result.linked.length > 0)
505
+ parts.push(`${result.linked.length} added`);
506
+ if (result.removed.length > 0)
507
+ parts.push(`${result.removed.length} removed`);
508
+ if (result.unchanged.length > 0)
509
+ parts.push(`${result.unchanged.length} unchanged`);
510
+ if (result.missing.length > 0)
511
+ parts.push(`${result.missing.length} missing`);
512
+ if (parts.length > 0)
513
+ prompts.log.step(parts.join(", "));
514
+ }
515
+ Prompt.sync = sync;
516
+ })(Prompt ||= {});
517
+
518
+ // src/cli/commands/add.ts
519
+ var RepoShape = z2.object({
520
+ description: z2.string().nullable().optional()
521
+ });
522
+ function isUrl2(value) {
523
+ return value.startsWith("http://") || value.startsWith("https://") || value.startsWith("git@") || value.startsWith("ssh://");
524
+ }
18
525
  function stem(value) {
19
526
  const clean = value.trim().replace(/\/+$/, "");
20
527
  if (clean.length === 0)
@@ -24,14 +531,14 @@ function stem(value) {
24
531
  const seg = raw.split("/").filter(Boolean).pop() ?? raw;
25
532
  return seg.replace(/\.git$/, "");
26
533
  }
27
- if (isUrl(clean)) {
534
+ if (isUrl2(clean)) {
28
535
  const seg = clean.split("/").filter(Boolean).pop() ?? clean;
29
536
  const raw = seg.split("?")[0] ?? seg;
30
537
  const full = raw.split("#")[0] ?? raw;
31
538
  return full.replace(/\.git$/, "");
32
539
  }
33
- const base = path.basename(clean);
34
- const parsed = path.parse(base);
540
+ const base = path6.basename(clean);
541
+ const parsed = path6.parse(base);
35
542
  if (parsed.name.length > 0)
36
543
  return parsed.name;
37
544
  return base;
@@ -74,10 +581,10 @@ async function apiDescription(url, accept) {
74
581
  return result.data.description ?? "";
75
582
  }
76
583
  function gitName(uri) {
77
- const dir = path.resolve(uri);
78
- if (!fs.existsSync(dir))
584
+ const dir = path6.resolve(uri);
585
+ if (!fs6.existsSync(dir))
79
586
  return "";
80
- if (!fs.statSync(dir).isDirectory())
587
+ if (!fs6.statSync(dir).isDirectory())
81
588
  return "";
82
589
  const proc = Bun.spawnSync(["git", "remote", "get-url", "origin"], {
83
590
  cwd: dir,
@@ -105,37 +612,37 @@ async function remoteDescription(uri) {
105
612
  return "";
106
613
  }
107
614
  async function prefill(uri) {
108
- const remote = isUrl(uri);
615
+ const remote = isUrl2(uri);
109
616
  const git = remote ? "" : gitName(uri);
110
617
  const name = git.length > 0 ? git : stem(uri);
111
618
  const description = remote ? await remoteDescription(uri) : "";
112
619
  return { name, description };
113
620
  }
114
621
  async function interactive(namePrefill, descPrefill) {
115
- const uri = await prompts.text({
622
+ const uri = await prompts2.text({
116
623
  message: "URL or local path to a git repo"
117
624
  });
118
- if (prompts.isCancel(uri))
625
+ if (prompts2.isCancel(uri))
119
626
  return;
120
627
  const input = uri.trim();
121
628
  const seed = await prefill(input);
122
- const name = await prompts.text({
629
+ const name = await prompts2.text({
123
630
  message: "Name",
124
631
  initialValue: namePrefill ?? seed.name
125
632
  });
126
- if (prompts.isCancel(name))
633
+ if (prompts2.isCancel(name))
127
634
  return;
128
- const description = await prompts.text({
635
+ const description = await prompts2.text({
129
636
  message: "Description",
130
637
  initialValue: descPrefill ?? seed.description
131
638
  });
132
- if (prompts.isCancel(description))
639
+ if (prompts2.isCancel(description))
133
640
  return;
134
641
  await run(input, name || undefined, description || undefined);
135
642
  }
136
643
  function autoLink(name) {
137
- const localFile = path.join(".llm", "dotllm.json");
138
- if (!fs.existsSync(localFile))
644
+ const localFile = path6.join(".llm", "dotllm.json");
645
+ if (!fs6.existsSync(localFile))
139
646
  return;
140
647
  const local = Config.Local.read();
141
648
  if (Config.Local.has(local, name))
@@ -148,7 +655,7 @@ function autoLink(name) {
148
655
  Prompt.sync(sync());
149
656
  }
150
657
  async function run(uri, name, description) {
151
- const spinner2 = prompts.spinner();
658
+ const spinner2 = prompts2.spinner();
152
659
  spinner2.start(`Adding ${uri}`);
153
660
  const needSeed = !name || !description;
154
661
  const seed = needSeed ? await prefill(uri) : { name: "", description: "" };
@@ -156,11 +663,11 @@ async function run(uri, name, description) {
156
663
  const desc = description ?? seed.description;
157
664
  const result = await add(uri, resolved || undefined, desc || undefined);
158
665
  if (!result.ok) {
159
- spinner2.stop(t.error(result.error));
666
+ spinner2.stop(defaultTheme.error(result.error));
160
667
  process.exit(1);
161
668
  return;
162
669
  }
163
- spinner2.stop(`${t.success("added")} ${t.primary(result.entry.name)} ${t.link(result.storePath)}`);
670
+ spinner2.stop(`${defaultTheme.success("added")} ${defaultTheme.primary(result.entry.name)} ${defaultTheme.link(result.storePath)}`);
164
671
  autoLink(result.entry.name);
165
672
  }
166
673
  var command = {
@@ -185,7 +692,7 @@ var command = {
185
692
  }
186
693
  },
187
694
  handler: async (argv) => {
188
- prompts.intro("dotllm add");
695
+ prompts2.intro("dotllm add");
189
696
  const uri = typeof argv.uri === "string" && argv.uri.length > 0 ? argv.uri : undefined;
190
697
  const name = typeof argv.name === "string" && argv.name.length > 0 ? argv.name : undefined;
191
698
  const description = typeof argv.description === "string" && argv.description.length > 0 ? argv.description : undefined;
@@ -197,8 +704,8 @@ var command = {
197
704
  }
198
705
  };
199
706
  export {
200
- stem,
201
- github,
707
+ codeberg,
202
708
  command,
203
- codeberg
709
+ github,
710
+ stem
204
711
  };